Took up from 2022/11/02
Date | Contents | Commit |
---|---|---|
20221102 | Dart | |
20221105 | Dart | |
20221109 | Dart | |
20221112 | Material Guide, Structure | |
20221116 | Widget | |
20221123 | Abstract class, Widget, Scaffold | |
20221127 | Container, Row, Column, Network Image | Code, Notion |
20221201 | SizedBox, Expanded, Repeated Widget | Code, Notion |
20221203 | Scroll, Recycler View, GridView, ListView, Navigator | Code, Notion |
20221207 | Card, Generic, Async | Notion |
20221210 | Navigator, Future | Notion |
20221214 | Stateful, Stateless | Notion, DartPad |
20221217 | Stateful, Stateless | Code, Notion, DartPad |
20221221 | NotificationListener, Provider | Code, Notion, DartPad |
20221224 | Provider | Code, Notion |
20221226 | GridView, Navigator 2.0, PushNamed | Code, Notion |
20221231 | Abstract class, Initializer, const | Code, Notion, DartPad |
20230103 | InkWell, GestureDetector, Changing class for retrieving values | Code, Notion, DartPad |
20230107 | WillPopScope, SafeArea, Mixin, Image Widget, Provider | Code, Notion |
20230111 | Data Model Restructuring, Provider | Code, Notion |
20230114 | Using provider, Adding Log provider | Code, Notion |
20230121 | List/Map Generic, PageView, Carousel Slide, go_router, BottomNavigationBar | Code, Notion |
20230122 | currentIndex(Active Icon), Controller, AutomaticKeepAliveClientMixin | Code, Notion |
20230124 | HTTP Package, Node.js, Future, Async/Await | Code, Notion |
20230128 | Future, Express | Code, Notion |
20230201 | TodoView, Todo Provider, Todo Model, Repos, Services | Code, Notion |
20230205 | post request, Visibility Widget, Loading Progress by Stack Widget, Enum | Code, Notion |
20230208 | Proxy Provider | Code, Notion |
20230211 | ProxyProvider, Builder, FutureBuilder | Code, Notion |
20230215 | FutureBuilder, Snapshot, Stream, | Code, Notion |
20230218 | Future, Async/Await | Code, Notion |
20230222 | Stream | Code, Notion |
20230226 | Android, IOS Deep Link | Code, Notion |
20230301 | Start building new application, PageView, controller, SingleChildScrollView, physics | Code, Notion |
20230305 | App Project1 | Code, Notion |
20230308 | App Project2(Drawer) | Code, Notion |
20230312 | Scroll Controller, Page Controller, Size(Context) | Code, Notion |
20230315 | Detail page, mounted, IgnorePointer, Loading, Stack | Code, Notion |
20230319 | TextBanner, TitleText, ReviewStar, Assert, GridView.builder | Code, Notion |
20230322 | BottomNavigationBar, Search Page, TextField, Platform Object | Code, Notion |
20230326 | TextEditingController, Wrap, InkWell, Feed, ListViewBuilder(Recycler) | Code, Notion |
20230330 | Factory Method, Data Setting | Code, Notion |
20230402 | Abstract Class | Code, Notion |
20230405 | Builder | Code, Notion |
20230408 | Map Data, Provider, Data UUID | Code, Notion |
20230416 | Clousure, Future | Code, Notion |
20230419 | Non-blocking, Compute, | Code, Notion |
20230423 | EventListner, Event Listner, Non-Blocking | Code, Notion |
20230426 | homeViewProvider | Code, Notion |
20230430 | Parallel Programming(Compute), provider, Data Processing | Code, Notion |
20230501 | Enum, Provider Data, Adapter Pattern | Code, Notion |
20230507 | Adapter Pattern | Code, Notion |
20230514 | Adapter Builder Pattern, Dart 3.0 : Record(gist) | Code, Notion |
20230521 | Upgrade to flutter 3.10.0, Base, Interface | Code, Notion |
20230524 | Service Structuring, Provider Restructuring | Code, Notion |
20230528 | Server, Firebase | Code, Notion |
20230531 | Docker, EC2 Environment | Notion |
20230604 | Nodejs MVC + Service 검색해서 꼭 찾아오기! | Notion |
20230606 | Docker | Notion |
20230611 | Nginx | Notion |
- init → 2. didChangeDependency → 3. build → 4. addpostFrameCallback → dispose
1, 2, 3순차적 호출(끝나는거 안기다리고 바로바로 출발) 3이 끝나면 그다음에 4
this.mounted
는 build가 끝났는지 여부를 체크한다.build
가 끝났으면true
, 안 끝났으면false
가 된다.
-
Survival Analysis
-
InkWell: 애니메이션과 같이 클릭할 수 있게 해주는 것.
-
GestureDetector : 애니메이션이 없고 클릭이나 제스쳐 이벤트를 받을 수 있는 위젯
-
**Card ** : Elevation 줄때
-
ListView : SingleChildScrollView가 적용되어 있다. 전체 다 만들어 놓고 시작
- ListView.builder : SingleChildScrollView를 쓰고 있다. 그러나, builder가 써있는 경우는 모두 미리 만들어 놓은 만큼만 보여주는 것. 이것을 안드로이드로 따지면 recycler view라고 부른다. 오브젝트 풀링이라고 부르기도 한다. Gridview, pageView의 경우도 빌더는 recycler view혹은 object pooling이 적용되어 있다.
- GridView, PageView도 SingleChildScrollView.
-
Wrap : Wrap 위젯은 자식을 줄이나 행으로 배치하고 공간이 부족해지면 자동으로 줄이나 행을 바꿔줍니다.
-
Factory Method :
-
Abstract
-
extends : 오버라이딩 하던 안하던 자유. 안하면 부모꺼 쓰는 것.
-
implements : 오버라이딩 해야 함. 단, abstract가 abstract를 상속하고 있으면 거기서는 오버라이딩 안해도 된다. 어차피 맨 아래서 다 하면 된다.
-
구현체를 만들지 않아 놓으면 extends, implements하나 어차피 밑에 내려가서 구현해야 한다.
Int a();
-
Dart에서는 인터페이스를 만들자 이러면, implements를 일단 하는건데 그럼에도 불구하고 extends하는 것일수도 있기 때문에 필요한 경우 구현체를 만들지 않아 놔야 한다.
-
extends하면 상위객체를 만들어 내야 한다는 것. extends를 했다는 것은 super로 무엇인가를 할 수 있다. 그런데 implements는 super를 쓸 수가 없다.
class A{} or abstract class A{} class B extends A{ void a(){ super.i; //0 this.i; // 0 } }
// 이건 문제 class A{} or abstract class A{} class B implements A{ void a(){ super.i; this.i; } }
extends
void main(){ B().a(); } abstract class A{ int i = 0; void c(); // extends 자체는 오버라이딩 하든 안하든 자유인데 구현체가 없으면 무조건 구현 해야 함. void d(){} } class B extends A{ @override void c(){}; void a(){ print(super.i); print(this.i); this.d(); super.d(); // super.c(); 는 불가능 } }
implements - 반드시 overriding이 필요하다.
void main(){ B().a(); } abstract class A{ int i = 0; void c(); void d(){} } class B implements A{ @override void c(){} int i = 1; void d(){ print("D"); } void a(){ // print(super.i); print(this.i); this.d(); // super.d(); // super.c(); } }
What if A is not an Abstract?
void main(){ A().c(); B().c(); } class A{ int i = 0; void c(){ print("void C inside A"); } void d(){} } class B extends A{ @override void c(){ print("void C inside B"); } int i = 1; void d(){ print("D"); } void a(){ print(super.i); print(this.i); this.d(); super.d(); super.c(); } }
-
-
Dart 3.0 Update - Interface 예약어
-
인터페이스와 추상클래스는 사실 다른 개념이다.
- 인터페이스 : 클래스를 어떻게 쓰겠다고 사전에 정의해 놓는 것. 함수마다 구현체가 들어있고 실제 로직이 들어가있다.
- 추상클래스: 구현체가 없는 함수를 만드는 행위
-
결국 구현체 여부의 차이일 뿐. 자식이 오버라이딩 해야 하는지 이런거는 관련이 없다.
- extends : 반드시 Overriding 할 필요는 없음. 그대로 가져가서 쓰면 됨.
- implements : 반드시 overriding이 필요하다.
-
Dart에서의 키워드(예약어)
- abstract : 추상 메서드를 만들 수 있게 해주는 키워드. 그걸 아래서 extends로 받을지 implements로 받을지는 그냥 선택의 문제.
- interface : 원래 인터페이스라는 개념은 다른 클래스에서 반드시 오버라이딩 해야 하는 클래스를 의미. 그니깐, 반드시 implements로 아래서 받아줘야 돼. 그런데 골때리는게 다트에서는 extends를 해도 되긴 된다.
- 그리고 interface라고 하면 중간 다리 안만들고 1:1로 써야 한다.
- 하위에 다른 인터페이스를 상속하지 않겠다는 의미가 큼.
-
결론
- interface 키워드 쓸꺼면 그냥 무지성으로 abstract쓰자. 구현체 없어도 되는 가능성을 열어주는건 나쁠게 없지. 추가적으로 객체생성도 방지할 수 있다.
- interface쓸꺼면 아래 다른 interface붙이지 말고 바로 클래스로 가자.
-
-
Dart 3.0 Update - Base 예약어
-
base는 말 그대로 실제 로직 구성에 베이스 클래스. ''기본이 되는 애''다 라는 것. 얘를 기본으로 두고, 실제로 쓸 클래스를 만들어 주는 것. 기본이 되는 로직. 아래서 extends해서 기본이 되는 애들의 추가되거나 변경되는 애들을 밑에서 써줄 수 있다. 누가 만들었는지 이런 것들을. base가 abstract/interface가 아닌데 extends가 된다.
-
abstract interface class ConnectInterface{ } base class Connect extends ConnectInterface{ } final class Connect_Noel extends Connect{ }
-
final 을 붙이면 더 이상 상속할 수 없다.
-
사실 정확히 말하면 상속이 안된다는게 같은 파일 내에서는 extends, implements가 되고 다른 파일에서는 안된다.
-
abstract interface class ConnectInterface{ } base class Connect extends ConnectInterface{ } final class Connect_Noel extends Connect{ } ConnectInterface connect = Connect_Noel();
-
-
void main(){
A ab = new B();
ab as B;
}
abstract class A{
}
class B implements A{
int c = 0;
}
현재 A에는 아무것도 없다. int c는 B에만 독립적으로 가지고 있는 변수이다. 그러면 이제 A타입으로 ab를 만들었으니깐, c라는 변수는 버린 상태에서 ab변수로 들어간다. 만약 c를 쓰고 싶으면 B타입으로 타입캐스팅을 해줘야 한다.
그러나, abstract일지라도 뭔가가 정의되어 있는 경우는 다르다.
void main(){
A ab = new B();
print(ab.d);
}
abstract class A{
int d = 1;
}
class B implements A{
@override
int d = 2;
int c = 0;
}
값을 출력할 수 있다. d는 2가 출력된다.
아래처럼 해도 d는 2가 출력된다.
void main(){
A ab = new B();
print(ab.d);
}
abstract class A{
int? d;
}
class B implements A{
@override
int? d = 2;
int c = 0;
}
즉, 구현체 공간, 선언 공간 이런게 따로 없다.
인터페이스도 변수 공간은 가지고 있다.
-
Builder : 반환하는 Widget의 Context로 잡아준다.
-
const가 붙은 생성자 : const라고 써서 생성자를 만들면, 그냥 생성자로도 이용할 수 있고, const 생성자로도 이용할 수 있게 되는 것. 생성자 함수가 두개인 것. const생성자를 허용하는 상태의 생성자를 만든 것. 예를 들어, 생성자에서
const BannerModel
을 해놨으면, BannerModel()을 만드는 곳에서도 앞에 const를 붙일 수 있다는 뜻이 된다.const BannerModel()
안붙이면 const가 안된다.
-
await
가 동일context
에서 걸려 있으면 그 아래로는 화살표 왔다갔다가 가능하다. 그러나 그 다음에await
가 안걸려 있으면 화살표가 왔다가 거기서 끝날때까지 기다려야 함으로 멈춘다. -
또한, 함수 내부 내부를 타고 들어가면서 실행할 때 안쪽에서 또 await가 없으면 거기서는 멈춘다.
-
통으로 넘겨줘서 쓰레드를 나눠서 별도의 공간에서 실행시키는 개념이
compute
이다. -
compute는 기본적으로 await를 붙인다. 왜냐면, Future를 리턴하기 때문에 거기서 실행하고 Future의 리턴값을 받아와야 한다. 그때 Future가 무엇을 리턴할 지는 우리가 정할 수 있다. 만약 await를 안붙이면? 말 그대로 Future를 돌려 받은 다음에 바로 다음 줄 실행하니깐, 그 Future의 리턴값을 쓸 수가 없다. await가 걸려 있어야 Future의 리턴을 기다린다.
- await를 안붙이면, Future반환 후 notifylistner를 작동하겠지. await가 걸려 있어야 Future가 반환할때까지 기다렸다가 notifylistner를 실행시키는 것.
void _init() async { Map<String, dynamic> _body = await this._fetch(); this._setBanner(_body['bn']); this._setHomeListProduct(_body['list']); this._setGridProduct(_body['grid']); await compute(); this.notifyListeners(); }
-
그런데, compute가 까다로운게 무조건 Top Level 함수여야 한다. 그것은 아래 두가지 중 하나의 함수여야만 한다.
- 전역함수
- Static 함수 (안에서 this를 못씀. 메서드랑 다르게 외부에서 그대로 가져다 써야되니깐 instance라는 개념이 없다)
-
그리고, 첫번째 파라미터로는 실행할 함수를, 두번째 파라미터로는 첫번째 함수의 파라미터로 넣어줄 함수를 써야 한다.
provider는 단순히 데이터(값)을 수정하는 부분만 들어가있고
service는 ‘비지니스 로직’이필요하다. 비지니스 로직이라는 것은 상태값을 바꾸게 하는 절차외 나머지. 상태값 바꾸는 절차외 나머지. 상태값을 만들어내거나, 서버와 통신하거나, 서버에 값을 보내거나.
repo는 서비스를 구현하기 위해 필요한 패키지들을 wrapping 해놓는 것.