본문 바로가기

오름캠프 flutter과정 정리

6일차 강의 정리(테스트 코드작성 및 캡슐화와 컬렉션)

# 6일차

참고로 클래스와 상관없이 사용하는 메서드나 변수와 같은 경우는  static 으로 사용하는것보다는 

top레벨로 활용하는 것이 좋다는 공식문서의 내용이 있었음

ctrl + d 한줄복사

ctrl + x 한줄삭제

## 테스트코드 작성 방법

테스트 할파일을 선택 후

 test 디렉토리 아래에 동일 위치에 _test 를 붙인 파일을 작성한다.

파일 안에 테스트 함수를 사용하기 위해서 import  ‘package:test/test.dart’와 테스트하려고 하는 파일을 임포트한다.

test함수를 통해서 

given 준비 

해당 파트에서는 테스트 하려는 객체및 데이터를 준비하는 단계이다 예를 들면 테스트 하려는 클래스에 대해서 생성하는 단계이기도 하다

when 실행

실제 테스트하려는 동작을 실제로 실행시키는 단계이다. 예를 들면 테스트 하려고 하는  객체의 메소드를 실제 실행하는 단계이다.

then 결과확인 

expect 함수에 1번째 파리미터로 확인하려는 값 , 2번째 파라미터로 기대되는 결과값을 

파라미터로 넘긴다.

의 순서대로 테스트 코드를 작성하고 테스트를 실행시킬경우  expect 함수중 하나라도 실행되어 검증하려는 값과 기대되는 결과값이 다르면 테스트 실패라고 뜬다.

## 캡슐화

이제 클래스나 인스턴스를 이용하여 현실세계를 객체 지향 프로그램으로 자유롭게 개발 할 수 있게 되었다. 하지만, 실수로 속성을 덮어 쓰거나, 잘못된 조작 하는 등의 휴먼 에러 (human error) 를 완전히 없앨 수는 없다. 그래서 Dart 에는 실수를 미연에 방지하는 “캡슐화" 라는 방법이 있다.

그래서 캡슐화를 하기 위해서 

우선 변수에 대해서 접근 지정자를 지정할 수 있다

| 제한 범위 | 명칭 | 설정 방법 | 접근 가능한 범위 |
| --- | --- | --- | --- |
| 제한이 엄격 | private | 멤버 앞에 _ 붙이기 | 자기 자신의 클래스 |
| 제한이 느슨 | public | 기본 값 | 모든 클래스 |

private 변수 설정시 변수명 앞에  붙는 _는 언더스코어가 공식 용어 이다. 

생성시에 private변수에 값을 할 당하기 위해서  아래 코드처럼 바꾸어야 한다. 

```dart
class Hero{
static int money = 100;
String name;
int _hp;
}

Hero({
required this.name,
reuqired int hp,
int _hp;
}):_hp = hp;
```

메소드의 경우 private으로 설정하기 위해서 아래 die처럼 메서드명앞에 _스코어 붙인다.

```dart
class Hero{
static int money = 100;
String name;
int _hp;
}

void _die(){
print();
}
```

클래스 다이어 그램에서 + 퍼블릭 -는 프라이빗이다



### **getter 와 setter**

메소드를 경유한 필드 조작

getter : 읽기 전용 프로퍼티를 구현할 때 사용

setter : 쓰기 전용 프로퍼티를 구현할 때 사용 (잘 안 씀)

getter는 다음과 같이 만든다.


이렇게 설명하면 아래와 같이 . 을 통해서 프라이빗한 변수에 접근 가능해짐 

```dart
Hero hero = new hero;
int hp = hero.hp
```

getter / setter 의 예



setter의 경우도 다음과 같이 . 을 통해서 프라이빗한 변수에 값할당가능  위의 예시처럼 

프러퍼티와 밖에서 접근하는 setter 이름이 다를 수도 있음

```dart
Vehicle vehicle = Vehicle();
vehicle.age= 2000;
```

**getter / setter 의 메리트**

1. Read Only, Write Only 필드의 실현
2. 필드의 이름 등, 클래스의 내부 설계를 자유롭게 변경 가능
3. 필드로의 액세스를 검사 가능

setter 에서 값의 타당성을 검사하기위해서 setter 사용


클래스 자체에 대한 엑세스 제어를 할 수 있다 

아래처럼 클래스명에 _ 를 붙여줌

```dart
class _A{}
```

**캡슐화란**

**개발자의 잘못된 접근에 대한 제어 방법을 제공**

## 정리

캡슐화의 개요

- 캡슐화를 하여 멤버나 클래스로의 접근을 제어할 수 있음
- 특히, 필드에 “현실세계에서 불가능한 값"이 들어가지 않도록 제어

멤버에 대한 접근 지정

- private 멤버는, 동일 클래스(파일)내에서만 접근 가능
- public 멤버는, 모든 클래스에서 접근 가능

클래스에 대한 접근 지정

- 함수, 변수와 동일한 규칙

## 컬렉션

데이터 구조에 따른 대표적인 컬렉션 (자료구조)

1. List : 순서 대로 쌓여있는 구조 (아이템의 중복 허용)
2. Map : 키(key)와 값(value)의 쌍으로 저장 (키의 중복 불가)
3. Set : 순서가 없는 집합 (중복 불가)

Dart 에는 Array(배열)이 없고 List만 있음


```dart
final names =[];// 해당방식으로 리스트선언시 다양한 자료형 넣을 수 있음 
                // 해당코드 처럼 자료형 생략시 다이나믹 자료형이 됨

names.add("이믈");
names.add(1);
names.add(10.5);
names.add(true); // 모두 가능

something(){

}// 해당받식으로 함수작성시 리턴타입이 dynamic 되어서 가능한한 반환형 자료형 써라
```

참고로 var은 컴파일타임에 타입 추론에 의해 타입결정 dynamic은 실행시에 타입추론에 의해 타입결정 dynamic은 런터임에 오류가 나기때문에 오류잡기 힘들어서 가능한 사용금지

List의 탐색 방법



forEach함수의 경우 입력을 하나만 받고 리턴타입이 void인 함수 이름만 써서 파라미터로 넘겨줄수 있음

### Set

중복 값을 허용하지 않는 집합

get() 메서드는 제공하지 않기 때문에 반복이 필요하면 Iterator를 사용하거나 forEach()를 사용

List의 contains(값이 있는지 없는지 확인하는 함수) 보다 압도적으로 빠름

get()지원하지 않는 이유는 Set은 순서가 없어서이다



Iterator

List나 Set 은 요소를 탐색할 수 있는 iterator 를 제공한다


### Map

키(key) : 값(value) 의 쌍으로 이루어진 요소를 담는 자료구조

키의 중복은 허용되지 않음



위의 예시처럼 Map을 클래스 처럼 다양한 자료형을 값으로 넣고 싶은경우 다이나믹을 사용한다.

Map 에 저장된 값을 하나씩 얻기


Map은 순서를 보장하지 않기 때문에 매번 출력 결과의 순서가 다르게 표시 될 수 있음

컬렉션의 응용

컬렉션 안에 컬렉션

Map<String, List<String>>

List<List<Hero>>



컬렉션 선택

- key, value 쌍 : Map
- 중복 가능 : List
- 중복 불가 : Set
- 순서 중요 : List
- 순서 안 중요 : Set
- 검색 속도 중요 : Set