ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [코드 팩토리의 플러터 프로그래밍] 2일차
    개발일기장/코드팩토리의 플러터 프로그래밍 2025. 3. 5. 15:11
    📋 목표
    - 코드팩토리 Dart 언어 입문 강의 2~3강 수강
    - 후기 및 이후 목표

     

    1️⃣ 객체지향 프로그래밍(OOP)과 함수형 프로그래밍(FP)

    객체 지향과 관련된 내용은 옛날에 Javascript에서 객체지향 과 관련된 내용을 공부할 때 접한 적이 있고 함수형 프로그램이은 Javascript의 거의 기본이라서 어떤 내용인지 유추가 될 것 같다. javascript와 관련이 깊은 Dart인만큼 호이스팅의 개념을 가지고 있는지 앞선 화살표 함수가 Javascript와 얼마나 유사한지는 좀 궁금하다.

     

    📦 객체 지향 프로그래밍 (OOP)

    처음 설명하는 부분을 듣고 있자니 정처기 준비하면서 배웠던 디자인 패턴 중 팩토리 메서드와 유사한 부분이 있는 것 같다.

    Object를 상속받기에 OOP라고 불림

     

    생성자를 통해서 instance를 손쉽게 생성하도록 class를 정의해보자

    void main() {
      Mcn pixel = Mcn(
        '픽셀',
        ['지누', '김뿡', '너불']
      );
      pixel.introduceMembers();
    }
    
    class Mcn {
      String name;
      List<String> members;
      
      Mcn(String name, List<String> members): this.name = name, this.members = members;
      // 간결하게 construncor 나타내기
      // Mcn(this.name, this.members)
      
      
      sayHello() {
        print("안녕하세요 저희는 ${name}입니다.");
      }
      
      introduceMembers() {
        String joinMember = members.join(", ");
        print("저희 멤버는 $joinMember입니다.");
    
      }
    }
    • join()의 사용방법은 js와 동일해서 쉽게 작성할 수 있었고, this를 사용하는 것이 뭔가 그리운 향수도 느껴진다.
    • constructor(생성자)를 만든는 문법이 좀 독특하지만 어느정도 인지 가능한 것 같다. 

     

    🔥 class 내에서 메서드를 선언할 때 this.name을 사용해야하나?

    더보기
    실제로 강의를 듣기 전 구현하는 과정에서는 sayHello나 introduceMembers에서 변수 값을 가져올 때 this를 사요하지 않았다. 하지만 원하는 값이 잘 출력되는 것을 알게 되었다. 그렇다면 어떤 경우에 에러가 발생하는지 내가 생각하는 부분을 정리해보고 실험해보자
    • 생성자보다 먼저 메서드가 선언될 수 있을까? 이때에서 this를 사용하지 않으면 어떻게 될까?
    void main() {
      Mcn pixel = Mcn(
        '픽셀',
        ['지누', '김뿡', '너불']
      );
      pixel.introduceMembers();
      pixel.testMethod();
    }
    
    class Mcn {
      ...  
      testMethod() {
        print('테스트입니다 ${name}');
        //    print('테스트입니다 ${this.name}');도 문제없이 사용 가능
      }
      
      Mcn(String name, List<String> members): this.name = name, this.members = members;
      
      ...
    }

    constructor보다 상위에 메서드를 선언하고 name값을 가져와서 사용해도 큰 문제가 없었다. 내가 원하는 테스트입니다 픽셀 output값이 나왔다. 

    • 호출부에서 값이 바뀌면 어떻게 될까? 그래도 다시 돌아올까?
    void main() {
      Mcn pixel = Mcn(
        '픽셀',
        ['지누', '김뿡', '너불']
      );
      Mcn sandbox = Mcn(
        '샌드박스',
        ['마뫄', '춘향']
      );
      pixel.introduceMembers();
      pixel.testMethod();
      sandbox.introduceMembers();
    }

    이상없이 내가 원한 출력값이 확인되었다. 그렇다면 왜 this를 사용해야하는걸까?

    ChatGPT
    1. this키워드를 통해서 가독성을 늘릴 수 있다. class 내부에서 사용되는 지역변수인지 아니면 인스턴스 변수인지 명확하게 알기 위해서 this키워드가 필요하다.
    2. 변수명의 충돌이 발생하는 경우에 반드시 this를 사용해야한다. class 내부 지역변수와 메서드의 argument로 받아오는 변수의 이름이 동일한 경우 this를 사용해서 두 변수를 구분할 수 있다.
    class Mcn {
      String name;
      
      Mcn(String name) {  // name 매개변수와 인스턴스 변수 이름이 같음
        this.name = name; // 'this'를 사용해 인스턴스 변수임을 명확히 함
      }
    }​

    네임드 constructor만들기

    constructor를 통해서 우리는 클래서에서 사용할 값들을 받을 수 있는데 일반적으로 constructor를 사용해서 값을 받아도 되고 네임드컨스트럭터라고 불리는 방식을 사용해서 만들어도 된다. 어떠한 방식을 사용하든 상관없지만 받아오는 값의 형식을 어떻게 표현하느냐와 어떻게 네임드 컨스트럭터를 사용할지 고민 좀 하면서 사용해야될 것 같다.
    void main() {
      Mcn pixel = Mcn('픽셀', ['지누', '김뿡', '너불']);
      Mcn sandBox = Mcn.fromList([
        '샌드박스',
        ['마뫄', '춘향'],
      ]);
      pixel.introduceMembers();
    }
    
    class Mcn {
      String name;
      List<String> members;
    
      Mcn(this.name, this.members);
      Mcn.fromList(List values) : this.name = values[0], this.members = values[1];
    
      sayHello() {
        print("안녕하세요 저희는 ${name}입니다.");
      }
    
      introduceMembers() {
        String joinMember = members.join(", ");
    
        print("저희 멤버는 $joinMember입니다.");
      }
    }

     

     class를 immutable하게 만들기

    class 변수들을 final 키워드를 사용해서 변경할 수 없게 해서 처음 선언 이후에도 값이 변경되는 것을 방지해야한다. const를 통해서 인스턴스를 생성하는 것도 좋다 이 때에는 컴파일 시에 값을 알 수 있는 값들로만 이루어짐 이 때 const로 선언할 때 내부 값이 같으면 주소값이 같아지네?? 이건 신기하네

     

    getter와 setter

    사실 getter, setter를 사용하는 것이 함수를 만들어서 사용하는 것과 기능적으로 큰 차이는 없지만 뉘앙스의 차이가 있다고 한다. 간단하게 사용할 수 있는 경우에는 getter와 setter가 좀 더 적합하고, 로직이 복잡해지는 경우 함수로 만들어 사용하는 것이 더 낫다고 한다.
    //   getter
      String get FirstMember {
        return members[0];
      }
    //   setter
      set setFirstMember(String name) {
        this.members[0] = name;    
      }
    • 여기서 class 변수들을 final을 통해서 외부에서 변환하지 못하도록한다면 setter를 사용하는 것도 불가능하기에 의미가 없어진다. 그래서 현대에서는 setter는 잘 사용이 안된다고한다. (immutable이 중요하지 그럼그럼)

    private 속성 사용하기

    앞에 _를 붙이면 privtate로 사용한다는 뜻이고 이렇게 되면 같은 파일 내에서만 사용할 수 있게 됨

     

    상속 - inheritance

    extends를 사용하는 것이 아주 쉽고만 쉬워 super도 사용하는 것이 JS와 문법이 동일하구나 상속을하게되면 타입이 부모도 될 수 잇고 자기 자신도 될 수 있는 건 좀 신기하네 JS도 이렇게 되나? 인스턴스의 타입을 비교하는 건 JS에서 한 적이 없는 것 같은데?

     

    메서드와 오버라이딩

    class 안에 선언된 함수를 메서드라고 하는데 오버라이딩을 통해서 다양한 메서드를 선언해보자.
    void main() {
      TimeTwo tt = TimeTwo(2);
      print(tt.calculate());
    }
    
    class TimeTwo {
      final int number;
      TimeTwo(this.number);
    
      int calculate() {
        return number * 2;
      }
    }
    
    class TimeFour extends TimeTwo {
      TimeFour(int number) : super(number);
    
      // 상속받은 부모의 메서드를 변경해서 사용하고 싶음
      @override
      int calculate() {
        return super.number * 4;
        // super 안써도 되고 this써도 되지만 super를 사용하는 게 가독성에 좋다.
        // return super.calculate() * 2; 이것도 같은 결과를 낸다. 선택 사항
        /// calculate는 this를 사용하면 무한루프에 걸린다.
      }
    }
    • 자바스크립트와 매우 유사한 개념을 보이면서 거의 문법도 비슷하다.

    static 종속의 개념

    // static에 대해서 알아보자
    void main() {
      // instance에 귀속되는 경우에는 만들어진 인스턴스에 값에 따라서 달라진다
      Employee marry = Employee('마리');
      
      // 이런식으로 class 자체에 귀속되게끔하면 내가 어떤 인스턴스를 만들든 중복된 값이 부여된다.
      Employee.building = '메가타워';
        
    }
    
    class Employee {
      // static은 instance에 귀속되지 않고 class에 귀속된다.
      static String? building;
      final String name;
      Employee(this.name);
      void printName() {
        print('제 이름은 $name이고, $building에서 근무중입니다.');
      }
    
      static void printBuilding() {
        print('$building에서 근무중입니다.');
      }
    }

     

    인터페이스 - interface

    인터페이스를 사용해서 형태를 지킬 수 있게끔할 수 있다. 이 때에는 implements라는 키워드를 사용하면된다. 형태를 강제하는 역할을 함. 타입스크립트에서 사용하는 인터페이스와 거의 비슷한 느낌 속성과 기능을 물려주는 상속, 형태를 강제하는 인터페이스
    인터페이스는 다른 클래스와 같이 인스턴스를 만드는 역할을 하는 것이 아니니깐 abstract를 선언해서 얘는 인스턴스로 만들 때 사용하지 말라고 키워드를 설정하는 것임.

     

    제너릭 - generic

    타입을 외부에서 받을 때 사용하는 것 타입스크립트에서 사용하던 것이랑 비슷할 것 같음.
    void main() {
      Lecture<String> lecture1 = Lecture('123', 'lecture1'); 
    }
    
    // generic
    class Lecture<T> {
      final T id;
      final String name;
      Lecture(this.id, this.name);
    }

     

    전체적은 강의 내용을 보았을 때는 map, where, reduce, fold 등등을 이용해서 구현을 하는 방식을 말하는 것 같다. 좀 더 복잡한 의미가 있겠지만 입문단계에서는 이렇게 알라는 의미인 것 같다. 함수형, 객체지향 파트까지 배웠는데 호이스팅에 대한 얘기가 없는 것을 보니 arrow founc는 그냥 단순히 축약의 기능만 하나 의심도 든다. 나중에 찾아봐야지

     

    () 를 사용하는 자료형태는 iterable이며 튜플이 아님 그냥 Map이나 Set으로 변환하기 쉬운 자료형태임 asMap(), toSet()을 통해서 return되는 값은 이런 자료형태를 가짐 이후 toList()를 통해서 리스트로도 만들 수 있음

    list를 가지고 핸들링하는데 map, filter, reduce가 나올 것만 같음. 불변성을 지키는 것까지 동일함 근데 list형태로 반환하는 것이 아닌 이터러블 형태로 반환되기에 toList()와 같은 추가적인 메서드가 있어야함

    Map형태에서는 JS에서는 map을 사용할 수 없었는데 여기서는 가능하다.

    void main() {
      Map<String, String> test = {'0': 'test1', '1': 'test2'};
      final result = test.map(
        (key, value) => MapEntry('testkey $key', 'nextNext $value'),
      );
      print(result);
    }

    Set에도 동일하게 적용할 수 있다. map을 굉장히 많이 활용할 수 있다.

    여기서에서는 filter가 아니라 where임 true일 경우 유지 false일 경우 삭제 해당 조건을 통과하는 값만을 남기는 filter, where

    reduce는 동일해보임 가장 큰 차이점이 reduce를 썼을 때 실행한 이터러블한 값의 구성요소들의 타입으로 반환이 되어야한 String으로 구성되어있는 리스트를 사용했다면 String이 return되어야지 int가 되면 안된다.

    그래서 reduce말고 fold를 사용할수도 있는데 이거는 반환되는 값의 타입을 직접 기입해줄 수 있다.

    다만 매개변수로 초기값, (accur, curr) 이러한 매개변수를 받음

     

    ... - cascading operator

    펼치는 역할로 JS랑 똑같은 역할을 하는구나.

     

    2️⃣ 후기 및 이후 목표

    ⛔️ 후기
    내일까지는 Dart에 대한 기본강의를 수강하고 1~3일차 총 통 틀어서 궁금했던 내용을 정리하는 시간을 가지면 좋을 것 같다. 아무래도 느끼기에는 겉핧기식으로 생략된 내용도 있다고 느껴진다. OOP와 FP에 대한 개념들 중 대다수는 JS에서 배울 때와 비슷한 개념이 많았고 사용하는 키워드를 언제 적절히 해야하는지 구분만 잘 하면될 것 같다. 끝으로 강의에서는 OOP의 활용도가 높다고 표현되는 부분이 있어서 React와는 달리 class에 대한 개념도 충분히 가지지 않으면 조금 힘들겠다는 생각도 든다.

    📋 이후 목표
    - 4강 비동기 프로그래밍 수강
    - 추가강의 업데이트 문법 수강
    - 1 ~ 3일차 되짚어보기

     

     

     

     

     

     

    댓글

Designed by Tistory.