Git Product home page Git Product logo

bookreview's People

Contributors

jungmyungjin avatar

Stargazers

 avatar

Watchers

 avatar

bookreview's Issues

디자인 패턴에 뛰어들기: SOLID 원칙

목차

기억하고 싶은 내용

SOLID 원칙

SOLID 원칙은 로버트 마틴이 소프트웨어 디자인을 보다 이해하기쉽고 유연하게 유지 관리 할 수있도록 하는 5가지 설계원칙에 대한 연상 기호다.

주의 : 이러한 원칙을 적용하기위해 노력하는게 좋지만 실용적인 적용인지 항상 의심하고, 이 모든것을 교리로 받아들이지 말아야 한다.

S :Single Responsibility Principle (단일책임 원칙)

클래스는 단 한가지 이유로 변경되어야 합니다.

각각의 클래스가 프로그램이 제공하는 기능의 한 부분을 책임지도록 하세요. 그 후 책임을 완전히 캡슐화하여 클래스 내부에 숨기세요.

Open/close Principle (개방/폐쇄 원칙)

클래스들은 확장에는 열려있어야 하지만 변경에는 닫혀 있어야 합니다.

L:iskov Substitution Principle (리스코프 치환 원칙)

클래스를 확장할 때 클라이언트 코드를 손상하지 않고 자식 클래스 객체들은 부모 클래스의 객체로 교환할 수 있어야 한다.

자식 클래스의 행동는 부모 클래스의 행동와 계속 호환되어야 한다. 메서드를 오버라이드할 때 기초 동작을 다른 행동으로 교체하지 않고 확장해야 한다.

  • 자식 클래스의 메서드의 매개변수 유형들은 부모 클래스의 메서드의 매개변수 유형들보다 더 추상적이거나 추상화 수준이 같아야 합니다.
  • 자식 클래스의 메서드의 반환 유형은 부모 클래스의 메서드의 반환 유형의 하위유형이거나 일치해야 합니다.
  • 자식 클래스의 메서드는 부모 클래스의 메서드가 예상했던 예외 유형들의 하위 유형이거나 그 유형과 일치해야 한다. 그렇지 않으면 예상치 못한 버그를 발생시킬 수 있다.
  • 부모 클래스의 불변속성은 반드시 보존되어야 한다.
  • 자식 클래스는 부모 클래스에 있는 비공개 필드 값을 변경해서는 안된다.

I:nterface Segreation Principle (인터페이스 분리 원칙)

클라이언트들은 자신이 사용하지 않는 메서드들에 의존하도록 강요해선 안된다.

클라이언트 클래스가 불필요한 행동을 구현할 필요가 없도록 인터페이스를 적당히 작게 만드세요. 그러지 않고 뚱뚱한 인터페이스로 변경한다면 변경된 메서들을 사용하지 않는 클라이언트들까지 망가뜨리게 됩니다.

서로 관련 없는 많은 메서드들을 하나의 인터페이스에 다 집어넣을 필요는 없습니다. 이것을 더 정제된 인터페이스들로 나누세요 필요하다면 그 전부를 단일 클래스에서 구현할 수도 있습니다

주의

  • 다른 원칙들과 마찬가지로 이 원칙도 너무 많이 사용하게 될 수 있습니다.
  • 인터페이스가 상당히 구체적이라면 더이상 나누지 마세요! 인터페이스가 많아질수록 코드는 더 복잡해진다는 사실을 잊지말고 균형을 유지하세요.

D: ependenct Inversion Principle (의존 관계 역전 원칙)

상위 계층 클래스들은 하위 계층 클래스들에 의존해서는 안됩니다. 둘 다 추상화에 의존해야 합니다. 추상화는 세부 정보들에 의존해서는 안됩니다. 세부 정보들이 추상화에 의존해야 합니다.

공감 모먼트

'때때로 사람들은 하위 계층 클래스들을 먼저 디자인한 다음 상위 계층 클래스들을 디자인하기 시작합니다. 이것은 새 시스템에서 프로토타입을 개발하기 시작할 때 매우 일반적입니다. 왜냐하면 이 시점에서는 하위 계층 기능들이 구현되지 않았거나 명확하지 않기 때문에 상위 계층에서 무엇이 가능한지조차 확신할 수 없기 때문입니다.'

  • 하지만 이러한 접근을 사용하 비즈니스 로직 클래스들이 하위 계층 클래스에 의존하게 되는 경향이 있다.
  • 하위 계층에 의존하는 대신 인터페이스에 의존하도록 하면 하위 계층에 의존하는 관계는 약해질 수 있다.

느낀점

OOP의 SOLID 원칙은 객체지향 프로그래밍을 할 때에 중요한 지표가 될 것으로 보이며, 객체지향을 한다면 계속 들여다보면서 체크를 해야할 것 같다. 지금은 클래스보단 함수를 많이 사용하고 클래스를 많이 만들거나 복잡한 클래스 로직을 다뤄보지 않아서인지 바로 사용하지는 못할 것 같았다. 사용하게 된다면 최근 본 이미지에디터 영역에서 사용할지도 모르겠다.

모던 리액트 DeepDive CHAPTER 02

목차

모던 리액트 DeepDive 02장 : 리액트 핵심 요소 깊게 살펴보기

기억하고 싶은 내용

JSX Element

JSXElementName

  • <$> <$n> : 가능
  • <_></_> : 가능
  • 그 외 숫자로 시작하거나, 다른 특수문자로 시작할 수 없다

JSXNameapacedName

  • JSXIdentifier:JSXdentifier의 조합
  • :를 통해 서로 다른 식별자를 이어주는 것도 하나의 식별자로 취급된다.
  • 두개 이상은 올바른 식별자로 취급되지 않는다.

ex) <foo:bar> </foo/bar>

JSXMemberExpression

  • JSXIdentifier.JSXIdentifier의 조합
  • .를 통해 서로 다른 식별자를 이어주는것도 하나의 식별자로 취급딘다.
  • .를 여러개 이어서 하는 것도 가능하다.
  • JSXNamespace와 이어서 사용하는 것은 불가능하다.

ex) <foo.bar> </foo.bar>

ex) <foo.bar.baz> </foo.bar.baz>

JSXAttributes

// JSXAttributeName 속성의 키로 값을 넣기
funtion vaild1(){
  return <foo.bar foo:bar="baz"> </foo.bar>
}

// JSX Attribute로 JSXElement 값 넣기
function child({attribute}){
  return <div>{attribute}</div>
}

export default function App({
  return (
  <div>
    <Child attribute=<div>hello</div> />
  </div>
  )
})

DOM과 브라우저 렌더링 과정

  1. 브라우저가 사용자가 요청한 주소를 방문해 HTML 파일을 다운로드한다.
  2. 브라우저의 렌어링 엔진은 HTML을 파싱 DOM 노드로 구성된 트리(DOM)를 만든다.
  3. 2번 과정에서 CSS파일을 만나면 해당 CSS 파일도 다운로드한다.
  4. 브라우저의 렌ㄷ링 엔진은 이 CSS도 파싱해 CSS 노드로 구성된 트리(CSSOM)를 만든다.
  5. 브라우저는 2번에서 만든 DOM 노드를 순회하는데, 여기서 모든 노드를 방문하는 것이 아니고 사용자 눈에 보이는 노드만 방문한다. 이는 트리를 분석하는 과정을 조금이라도 빠르게 하기 위해서다.
  6. 5번에서 제외된, 눈에 보이는 노드를 대상으로 해당 노드에 대한 CSSOM 정보를 찾고 여기서 발견한 CSS 스타일 정보를 이 노드에 적용한다.
    • 이 DOM 노드에 CSS를 적용하는 과정은 두가지로 나뉜다.
      1. 레이아웃 : 각 노드가 브라우저 화면의 어느 좌표에 정확히 나타나야 하는지 계산하는 과정.
      2. 페인팅 : 레이아웃 단계를 거친 노드에 색과 같은 실제 유효한 모습을 그리는 과정

가상 DOM

  • 렌더링 이후 추가 렌더링 작업은 하나의 페이지에서 모든 작업이 일어나는 싱글 페이지 애플리케이션에서 더욱 많아진다.
  • 이는 하나의 페이지에서 계속해서 요소의 위치를 재계산한다.
  • SPA의 특징 덕분에 사용자는 페이지의 깜빡임 없이 자연스러운 웹 페이지 탐색을 할 수 있지만 그만큼 DOM을 관리하는 과정에서 부담해야 할 비용이 커진다.
  • 사용자의 인터렉션에 따라 DOM의 모든 변경 사항을 추적하는 것은 개발자 입장에서 수고스러운 일이다.
  • 이러한 문제점을 해결하기 위해 탄생한 것이 가상DOM이다. 가상 DOM은 웹페이지가 표시해야 할 DOM을 일단 메모리에 저장하고 리액트가 실제 변경에 대한 준비가 완료됐을 때 실제 브라우저의 DOM에 반영한다.
  • 이렇게 DOM 계산을 브라우저가 아닌 메모리에서 계산하는 과정을 한 번 거치게 된다면 실제로는 여러 번 발생했을 렌더링 과정을 최소화 할 수 있고 브라우저와 개발자의 부담을 덜 수 있다.

가상DOM의 오해

  • 가상 DOM의 방식이 무조건 빠르다는 오해가 있다.
  • 그러나 이는 리액트 개발자인 댄 아브라모프(dan_abramov)가 사실이 아니라고 부정한 바 있다. 무조건 빠른 것이 아니라 리액트의 이 가상 DOM 방식은 대부분의 상황에서 웬만한 애플리케이션을 만들 수 있을 정도로 충분히 빠르다는 것이ㅏㄷ.

리액트 파이버(fiber)

파이버는 파이버 재조정자(fiber reconciler)가 관리하는데, 이는 앞서 말한 가상 DOM과 실제 DOM을 비교해 변경 사항을 수집하며, 만약 이 둘 사이에 차이가 있으면 변경에 관련된 정보를 가지고 있는 파이버를 기준으로 화면에 렌더링을 요청하는 역할을 한다.

파이버와 가상 DOM

  • 가상 DOM은 오직 웹 애플리케이션에서만 통용되는 개념이다.
  • 리액트 파이버는 리액트 네이티브와 같은 브라우저가 아닌 환경에서도 사용할 수 있기 때문에 파이버와 가상 DOM은 동일한 개념이 아니다.
  • 리액트와 리액트 네이티브의 렌더러가 서로 다르더라도 내부적으로 파이버를 통해서 조정되는 과정은 동이랗기 때문에 동일한 재조정자를 사용할 수 있다.

=> 리액트 내부의 파이버와 재조정자가 내부적인 알고리즘을 통해 관리해줌으로써 효율적으로 유지보수하고 관리할 수 있게 된 것이다.

클래스형 컴포넌트

PureComponent 와 Component

  • PureComponent는 state 값에 대해 얕은 비교를 수행해 결과가 다를 때만 렌더링을 수행한다. 그러나 모든 컴포넌트를 PureComponent로 사용하는게 좋은것만은 아니다. PureComponent는 얕은 비교만 수행하기에 state가 객체와 같이 복잡한 구조의 데이터 변경은 감지하기 못하기 때문에 제대로 작동하지 않는다.
  • 따라서 적재적소에 활용하는것이 애플리케이션 성능에 도움이 된다.

함수형 컴포넌트와 클래스형 컴포넌트

  • 함수형 컴포넌트는 렌덜이이 일어날 때마다 그 순간으 값인 props와 state를 기준으로 렌더링된다.
  • 반면 클래스형 컴포넌트는 시간으 흐름에 따라 변화하는 this를 기준으로 렌더링이 된다.

메모이제이션은 무조건 필요하다 vs 메모이제이션을 섣불리 해서는 안된다.

'렌더링 과정의 비용은 비싸다, 모조리 메모이제이션 해버리자' 진영의 주장

  • 잘못된 memo로 지불해야하는 비용은 props에 대한 얕은 비교가 발생하면서 지불해야 하는 비용이다.

  • 메모이제이션을 위해서는 CPU와 메모리를 사용해 이전 렌더링 결과물을 저장해야하고 리렌더링할 필요가 없다면 이전 결과물을 사용해야한다. 그런데 이 작업은 어디서 들어본 적 있지 않은가? 리액트는 이전 렌더링 결과를 다음 렌더링과 구별하기 위해 저장해둬야한다. 그것이 기본적인 재조정 알고리즘이기 때문이다.

    어차피 리액트의 기본적인 알고리즘 때문에 이전 결과물은 어떻게든 저장해두고 있다. 따라서 우리가 memo로 지불해야 하는 비용은 props에 대한 얕은 비교 뿐이다.

반면 memo를 하지 않았을 때 발생할 수 있는 문제

  1. 렌더링을 함으로써 발생하는 비용
  2. 컴포넌트 내부의 복잡한 로직의 재실행
  3. 그리고 위 두가지 모두가 모든 자식 컴포넌트에서 반복해서 일어남
  4. 리액트가 구 트리와 신규 트리를 비교

'메모이제이션을 섣불리 해서는 안된다' 진영의 주장

  • 메모이저에션도 어디까지나 비용이 드는 작업이므로 최적화에 대한 비용을 지불할 때에는 신중해야 한다.

  • PureComponentdㅘ 관련해 리액트 개발자인 댄 아브라모프는 다음과 같이 트윗을 남긴 적 있다

    아무 데서나 PureComponent를 쓰지 마세요.

    왜 모든 컴포넌트에 memo()를 기본값으로 사용하지 않나요? 그게더 빠르지 않나요?

    스스로에게 물어보세요.

    왜 lodash의 모든 함수에 memoize()를 사용하지 않나요? 혹시 벤치마크로 성능을 확인해 봐야 하지 않을까요?

  • 그리고 리액트 공식문서에 다음과 같은 내용도 나와 있다

    useMemo는 성능 최적화를 위해 사용할 수는 있지만 의미상으로 그것이 보장된다고 생각하지는 마세요. 가까운 미래에 리액트에서는 이전에 메모이제이션된 값들의 일부를 "잊어버리고" 다음 렌더링 시에 그것들을 재계산하는 방향을 택할지도 모르겠습니다.

    예를 들면 오프스크린 컴포넌트의 메모리를 해제하는 등이 있을 수 있습니다. useMemo를 사용하지 않고도 작동할 수 있도록 코드를 작성하고 그것을 추가해 성능을 최적화 하세요.

    따라서 useMemo를 언제까지고 성능 최적화를 위해 제공해 줄 것이라는 보장은 없다.

저자의 추천

리액트를 배우고 있거나 혹은 리액트를 깊이 이해하고 싶고, 이를 위해 시간을 투자할 여유가 있다면?

  • 섣부른 메모이제이션을 지양하는 자세를 견지하며, 실제 어느 지점에서 성능상 이점을 누릴 수 있는지 살펴보는 식으로 메모이제이션을 적용하는 것을 권장한다.

현업에서 리액트를 사용하고 있거나 실제로 다룰 예정이지만 성능에 대해 깊게 연구해 볼 시간적 여유가 없는 상황이라면?

  • 일단 의심스러운 곳에는 먼저 다 적용해 볼것을 권장한다.

  • lodash나 간단한 함수의 경우와는 다르게 일반적으로는 props에 대한 얕은 비교를 수행하는 것보다 리액트 컴포넌트의 결과물을 다시 계산하고 실제 DOM까지 비교하는 작업이 무겁고 비싸다.

  • 조금이라도 로직이 들어간 컴포넌트는 메모이제이션이 성능 향상에 도움을 줄 가능성이 크다.

  • useMemo와 useCallback 또한 마찬가지다. useCallback의 경우는 대부분 다른 컴포넌트의 props로 넘어가는 경우가 많을 것이다. 이 props로 넘어갔을 때 참조 투명성을 유지하기 위해서는 useCallback을 사용하는 것이 좋다.

느낀점

  • 리액트의 핵심요소에 대한 깊은 내용들을 다뤘던 장이다.
  • 파이버 라던가, 클래스형 컴포넌트의 여러 메서드와 렌더링과정, 생성주기는 중요하다는 것을 알면서도 한번에 머릿속에 각인되지는 않은것 같다. 좀 더 클래스컴포넌트의 다양한 활용을 해봐야 이해가 될 것 같다.
  • 메모이제이션 관련 코드 최적화에 대한 내용이 제일 흥미로웠는데, 메모이제이션을 할 때 비용이 많이 들어 주의를 해야한다 라는 주장에 대한 글만 봐왔던지라, 무조건 "메모이제이션을 무조건 해야한다" 라는 진영의 주장과 근거는 새로웠다. 이전 까지는 메모이제이션이 조심스러웠는데 이 글을 읽고 좀 더 메모이제이션을 적용해보려고 해야겠다는 생각이 들었다.
  • 이번 2장은 난이도가 5점만점의 4점인것 같다. "이런게 있구나~" 하고 넘어간 부분이 꽤 있어서 아쉬움이 있다.

디자인 패턴에 뛰어들기: 팩토리 메서드 패턴

목차

기억하고 싶은 내용

팩토리 메서드 패턴

부모 클래스에서 객체들을 생성할 수 있는 인터페이스를 제공하지만, 자식 클래스들이 생성될 객체들의 유형을 변경할 수 있도록 하는 생성 패턴이다.

팩토리 메서드를 사용하는 코드를 종종 클라이언트 코드라고 부르며, 클라이언트 코드는 다양한 자식 클래스들에서 실제로 반환되는 여러 제품 간의 차이에 대해 알지 못한다. 클라이언트는 모든 객체들이 메서드를 가져야 한다는 사실을 잘 알고있지만, 그 메서드가 정확히 어떻게 작동하는지는 중요하지 않는다.

팩토리 메서드는 항상 새로운 인스턴스들을 생성해야 할 필요가 없다.

적용

  • 팩토리 메서드는 대상 코드가 함께 작동해야 하는 객체들의 정확한 유형들과 의존관계들을 미리 모르는 경우 사용하세요.

    TIP : 팩토리 메서드는 제품 생성 코드를 실제로 사용하는 코드와 분리합니다. 그러면 제품 생성자 코드를 나머지 코드와는 동립적으로 확장하기 쉬워집니다.

  • 팩토리 메서드는 당신의 라이브러리 또는 프레임워크의 사용자들에게 내부 컴포넌트들을 확장하는 방법을 제공하고 싶을 때 사용하세요.

장점

  • 크리에이터와 구상 제품이 단단하게 결합되지 않도록 할 수 있다.
  • 단일 책임 원칙. 생성 코드를 프로그램의 한 위치로 이동하여 코드를 더 쉽게 유지관리할 수 있다.
  • 개발 폐쇄 원칙. 기존 클라이언트 코드를 훼손하지 않고 새로운 유형의 제품을 도입할 수 있다.

단점

  • 패턴을 구현하기 위해 많은 새로운 자식 클래스들을 도입해야 하므로 코드가 더 복잡해질 수 있다. 가장 좋은 방법은 크리에이터 클래스들의 기존 계층구조에 패턴을 도입하는 것이다.

느낀점

팩토리 패턴은 클래스를 추상화 하는 클래스를 만드는 패턴인것 같다. 개념적인 예제코드를 보니 어딘가 연습문제에서 해본것 같기도 하다. 이 패턴을 구현할때 추상화를 하는게 어려울 것 같다. 실제로 도입 후에 추상화 코드를 수정하는 일이 많을지 궁금하다.

CHAPTER 1 자바스크립트에서 타입스크립트로

목차

기억하고 싶은 내용

  • 자바스크립트처럼 충돌 가능성을 먼저 확인하지 않고 코드를 실행하는 동적 타입언어이다.
  • 다른 언어는 컴파일러가 충돌할 수 있다고 판단하면 코드 실행을 거부할 수 있다.

타입스크립트에 대한 오해

  • 타입스크립트는 독단적인 프레임워크가 아니라 모든 개발자들이 사용할 수 있다. 그렇기에 어떠한 코드 스타일을 가용하지 않으며, 특정 애플리케이션 프레임워크와도 연관되어 있지 않다.
  • 타입스크립트는 자바스크립트의 작동 방식을 변경하지 않는다.
  • 타입스크립트는 자바스크립트보다 느리지 않는다, 빌드 되는데의 시간이 걸리지만 빌드 후 런타임 시간은 자바스크립트와 동일하다

느낀점

  • 자바스크립트를 사용하며 자유분방한 모습이 좋았으나, 한 편으론 런타임 에러를 미리 못잡는 것에 있어서 당황스러운 부분이 많았다. 이 점을 개선한게 타입스크립트 같다.
  • 이 챕터에선 이전 자바스크립트를 사용했을때의 불편한점을 짚어주며, 타입스크립트가 나타나게된 배경을 알려주었는데, 실제로 사용했을때 느낀점과 동일하여 공감을 샀다.

함께자라기 1장 - 230626

목차

기억하고 싶은 내용

그래서 나는, 내가 구글에서 매일 하는 업무와 브레인 스토밍을 비교해보았다. 생각해보니 내가 일을 가장 잘했던 때는, 중요한 과제가 주어졌는데 시간이 충분하지 않았을 때였다.

  • 최근 프로젝트 경험이 없단 찰나에, 2주라는 짧은 시간에 쇼핑몰 사이트를 구현해야 하는 일이 있었다. 정말 아무것도 모르는 상태에서 구현을 해야한다고 하니, 시간이 너무 촉박하고 잘 할 수있을까 의심스러웠다. 그러나 팀으로 함께 하다보니 2주안에 계획했던 사이트는 구현을 할 수 있었고, 그 과정에서 많은 것을 배우게 되었다.
  • 사실 이전에 웹프론트엔드 공부를 하려고 강의를 듣거나 작은 페이지를 만들어 보기도했었다. 그러나 가장 효율적이며 크게 성장 했었던건 팀프로젝트를 함께 했던 순간이었다. 이 대목에서 크게 공감을 했다.

위험요소가 있는 아이디어가 스프린트에서 성공을 거두었을 때의 보람은 엄청나다. 하지만 스프린트에서 아이디어가 실패했을 때는 실망스러워도 투자 대비 효과가 가장 높다. 단 5일간의 작업으로 치명적 결함을 발견한다면, 능률면에서 최고가 아니겠는가.

  • 이전에 말했듯이 강의를 템포에 맞춰 천천히 듣거나 웹페이지를 혼자 만들어본 경험을 미루어 보아, 투자 대비 효율은 팀 프로젝트를 했을 때였다. (사실 팀프로젝트도 이전에 강의나 웹페이지를 만든 경험이 밑거름이 되었다)
  • 짧은 시간동안 부딪쳐보고 실제로 만들어진 결과물을 보며 성취감을 느끼며, 부족한 점을 스스로 깨닫는 부분에서 많이 공감이 되었다.

스프린트 운영방법

월요일 : 지도 그리기 & 타깃 선택

화요일 : 서로 경합을 벌이는 솔루션들 스케치

수요일 : 가장 좋은 솔루션 결정

목요일 : 진짜같은 프로토타입 제작

금요일 : 표적 고객과 테스트

스프린트 준비하기

스프린트 준비하기

스프린트를 시작하기 전에 먼저 적절한 과제를 선택하고 적임자들로 팀을 구성해야 한다. 또한 스프린트를 진행할 시간을 확보하고 장소도 구해야한다.

  • 기억해야지..

힘든 과제일 수록 스프린트의 효과가 높아진다.

  • 중대한 이해관계가 걸려 있을 때

  • 시간이 충분하지 않을 때

  • 곤경에 빠졌을 때

    어떤 중요한 프로젝트들은 일단 시작하기 어렵다. 진행 도중 힘이 떨어지는 프로젝트들도 있다. 이런 상황에서 스프린트는 부스터 로켓 역할을 할 수 있다. 즉, 중력의 저항을 이기고 추진력을 얻도록 돕는 새로운 문제 해결 방식이 될 수 있다.

  • 짧은시간을 주고 일정관리를 해가며 문제를 해결하다보면 부스터 로켓 역할을 할 수 있다는 점에 공감한다.

먼저 외양을 해결하라.

외양은 중요하다. 제품이나 서비스가 고객과 만나는 지점이 바로 외양이기 때문이다. 인간은 복잡하고 변덕스러운 존재라서 고객이 새로운 솔루션에 어떻게 반응할지 예측하기란 사실상 불가능 하다. 새로운 아이디어가 실패하는 까닭은 대게 고객들이 그 아이디어를 쏙쏙 잘 이해하고 관심을 기울일 것으로 과신했기 때문이다.

적절한 외양이 만들어지면, 그 기반이 되는 시스템이나 기술을 생각해내는 데 도움이 된다. 또 외관에 초점을 맞추면, 실제 구현 작업에 들어가기 전에 신속하게 일을 진행하고 중요한 의문점 들에 대한 답을 찾을 수 있다. 아무리 큰 과제라도 스프린트에서 도움 받을 수 있는 건 이 때문이다.

  • 웹 프로젝트를 처음 진행하며, pigma로 외양적인 구성을 완성하고 진행을 해보았다. 이전 기획에서 이야기를 나누었을 때 서로 생각이 달랐던 부분도 만들어진 외양을 보며 서로 의견을 나눌 수 있어서 좋았고, 실제 개발하는 과정에서 기획에 대한 고민이 적었다. 굳이 pigma를 사용하지 않더라도, 프로젝트 시에 외양에 대해 되도록 자세히 잡아가는 편이 좋다고 다시금 느꼈기에 이 대목에서도 크게 공감하였다.

느낀점

최근 3주간동안 웹사이트를 만드는 7명의 팀 프로젝트를 진행하였다. 최근에 진행하게 된 프로젝트에서 여러가지 느낀바가 많았는데, 제일 크게 느꼈던 교훈은 '무모하게 도전하고 결과를 이루기 위해 달리자' 였다. 사실 나는 무모하게 일을 벌려놓는다기 보단, ''할 수 있는 만큼만 제대로 하자' 라는 성향이 강했다. 그러나 이번 팀 프로젝트에서 기획할 당시에는 무작위로 팀이 짜진 것이라 팀원들의 개인 능력을 몰라서였는지 현실적인 가능성을 염두하지 않고 무작정 멋진 사이트를 만들기 위한 기획을 담았다. 사실 다른 팀원들의 의견은 어떨지 모르겠지만, 나의 개인적인 마음으론 이게 될까..? 싶었다.
그러나 실제로 모든 팀원이 결과를 위해 전력 질주를 하다보니 결과를 이루게 되었다. 나중에 이에 대해 이야기를 하다보니 스프린트라는 내용에 대해 알게되었다. 내가 겪었던 상황에 대해 공감할 부분과 배울부분이 많을 것 같아. 지금 시점에 읽으면 좋을 것이라 생각하여 읽게 되었다.

디자인 패턴에 뛰어들기: OOP(객체지향 프로그래밍)의 4가지 기본 개념, 디자인 패턴

목차

OOP(객체지향 프로그래밍)의 4가지 기본 개념, 디자인 패턴

기억하고 싶은 내용

내가 이해한대로 몇가지는 바꾼 내용

OOP(객체지향 프로그래밍)의 4가지 기본 개념

  1. 추상화 : 필요한 행동을 모델링하는 것. 간소화
  2. 캡슐화 : 필요한 인터페이스만을 남기고 그 외엔 접근을 제한하여 보호한다.
  3. 다형성 : 같은 이름의 메소드가 다양한 방식으로 동작할 수 있다. (오버로딩, 오버라이딩)
  4. 상속 관계 : 기존 클래스 위에 새 클래스 구축을 하는 기능

디자인 패턴의 분류

  • 생성 패턴 : 기존 코드를 재활용하고 유연성을 증가시키는 객체 생성 매커니즘 제공
  • 구조 패턴 : 구조를 유연하고 효율적으로 유지하면서 객체와 클래스를 더 큰 구조로 조합
  • 행동 패턴 : 객체 간의 효과적인 의사소통과 책임 할당을 처리

디자인 패턴의 장점

  • 디자인 패턴은 소프트웨어 디자인의 일반적인 무제들에 대해 시도되고 검증된 해결책을 모은것이다.
  • 함께 일하는 동료 팀원들이 디자인 패턴을 이해하면 의사소통하는데 사용할 수 있는 공용 언어가 늘어난다. 예를 들어 '이 문제를 해결하려면 싱글턴을 사용하세요' 라고 하면 모두가 어떤 뜻으로 이해했는지 알 수 있다.

좋은 디자인의 특징

  • 코드 재사용

    • '모든 소프트웨어 제품을 개발할 때 가장 중요한 두 가지 지표는 비용과 시간이다.'
    • 코드 재사용은 개발 비용을 줄이는 가장 일반적인 방법의 하나이다.
    • 그러나
      • 이론상은 훌륭하지만, 새로운 상황에서 기존 코드를 활용하여 동작하게 하는것은 쉽지 않다. 컴포넌트 간의 단단한 결합, 인터페이스 대신 구상 클래스들에 대한 의존 관계, 하드 코딩 등 여러가지 요인들이 코드의 유연성을 감소시키고 재사용을 어렵게 하기 때문이다.
      • 디자인 패턴을 사용하는 것은 소프트웨어 컴포넌트들의 유연성을 높이고 재사용하기 쉽게 만드는 한 가지 방법이다. 그러나 이 방법들은 때때로 컴포넌트들을 더 복잡하게 만든다.
  • 확장성

    • 공감 모먼트

      ‘대부분 소프트웨어 개발자들은 이와 같은 상황들을 수십 번 이상 경험했을 것입니다. 이러한 상황들이 발생하는 데는 몇 가지 이유가 있습니다.

      첫 번째 이유는 일단 문제를 해결하기 시작하면 문제를 더 잘 이해할 수 있기 때문입니다. 종종 개발자들은 앱의 첫 번째 버전의 개발을 끝마칠 때쯤에 문제의 여러 측면을 훨씬 더 잘 이해하기 때문에 처음부터 다시 개발하고 싶어 할 수 있습니다. 또, 개발자로서의 실력이 향상된 덕분에 작성한 코드가 쓰레기처럼 보일 수도 있습니다.

      두 번째 이유는 통제할 수 없는 무언가가 변경되었기 때문입니다. 이는 많은 개발 팀들이 원래 아이디어에서 새로운 아이디어로 선회하는 이유입니다. 예를 들어 온라인 앱에서 플래시에 의존했던 개발자들은 브라우저들이 플래시에 대한 지원을 중단했을 때 코드를 재작성하거나 마이그레이션해야 했습니다.’

‘좋은 소프트웨어 디자인이란 무엇일까요? 그리고 그건 어떻게 측정할까요? 또 이를 달성하기 위해서는 어떤 관행을 따라야 할까요? 아키텍처를 유연하고 안정적이며 이해하기 쉽게 만드는 방법은 무엇일까요?
훌륭한 질문들이나 불행히도 정답은 개발 중인 앱의 유형에 따라 다릅니다. ’

chatGPT에게 해결 방법을 물으면 늘 정답은 상황에 따라 다르다고 한다.

  • 캡슐화하기

디자인 원칙

  • 변화하는 내용을 캡슐화하세요
    • ‘당신의 앱에서 변경되는 부분들을 식별한 후 변하지 않는 부분들과 구분하세요.’
  • 구현이 아닌 인터페이스에 대해 프로그래밍하세요
    • 구상 클래스가 아닌, 추상화에 의존하도록 한다.
  • 상속보다는 합성을 사용하세요.
    • 재사용하는 확실하고 쉬운방법이 상속이지만, 상속은 주의해야할 점이 있다.
      • 상속의 문제점
        • 자식 클래스는 상위 클래스 인터페이스를 줄일 수 없다.
        • 메서드를 오버라이드할 때 새 행동이 base 행동과 호환되는지 확인해야 한다.
        • 상속은 부모 클래스의 캡슐화를 깨트린다.
        • 부모 클래스를 변경하면 자식 클래스 기능들이 손상될 수 있다.
        • 상속을 통해 코드를 재사용하려고 하면 병렬 상속 계층 구조들이 생길 수 있다.

느낀점

이 책의 초반부분을 읽으면서 우려했던것보단 책이 잘 읽혔고, 디자인 패턴을 왜 읽어야 하는지에 대해 설명이 적혀있어 납득이 갔다. 특히 디자인 패턴을 이해하면 팀원간의 의사소통을 하는데에 사용 되는 공용 언어가 늘어난다는 문장에 동의가 됐다. 객체지향에 대한 내용이 많을 것 같지만, 디자인 패턴에 대해 알게된다면 좀 더 시야가 넓어질 것 같다.

모던 리액트 DeepDive CHAPTER 01

목차

모던 리액트 DeepDive 01장 : 리액트 개발을 위해 꼭 알아야 할 자바스크립트

기억하고 싶은 내용

undefined = 선언이 되었지만 값이 아직 할당되지 않은 값

null = 명시적으로 비어있음을 나타내는 값

Object.is 와 ===

=== 연산자와 같이 타입이 다르면 false 로 나오는 점은 같으나, Object.is가 좀 더 개발자가 기대하는 방식으로 정확히 비교한다.

-0 === +0 // true
Object.is(-0, +0) // false


Number.NaN === NaN // false
Object.is(Number.NaN, NaN);

NaN === 0 / 0 //false
Object.is(NaN, 0/0) // true
  • ES6에서 새롭게 도입된 비교 문법이다.
  • 객체 간 비교에서는 === 와 동일하게 동작한다.

Object.is 를 사용한 예 - shallowEqual

일급객체

이 객체가 연산에 관련된 모든것을 할 수 있는것.

예를들면 자바스크립트의 함수는 일급 객체이다. 자바스크립트의 함수는 인수일수도, 리턴값 일 수도, 변수에 넣을수도 할당도 될 수 있기 때문이다.

함수 선언문과 함수 표현식의 차이.

함수 선언문은 '함수의 호이스팅'이 발생하여 선언 시점 이전에도 사용이 가능하다.

함수 표현식은 '변수의 호이스팅'이 발생하여 선언 시점 이전엔 undefined로 초기화 된다.

화살표 함수와 일반함수의 제일 중요한 차이점은 this이다.

  • 화살표 함수 : 상위 스코프의 this

  • 일반 함수 : 전역 객체의 this

    • 메서드 함수 : 객체의 this

    • 생성자 함수 : instance의 this

💡 useEffect의 콜백 함수에 네이밍을 붙여준다면 가독성에 도움이 된다.

useEffect(function apiRequest(){
// .. anything..
},[])

물론 위와 같이 콜백함수에 이름을 넣는다 한들 apiRequest()와 같이 접근할 수 있는건 아니다.

클로저로 useState 와 같은 커스텀 훅 함수 만들기

function COunter(){
	var counter = 0;
	return{
    increase: function(){
      return ++counter
    }
    decrease: function(){
      return --counter
    }
    counter: function (){
      console.log('counter'에 접근)
    }
	}
}

객체를 변수에 있는 값으로 꺼내오기

const key= 'a';
const object = {
  a: 1,
  b: 1
}

const {[key]:a} = object // a = 1
const {[key]} = object // ERROR !! 변수 네이밍을 하지 않음

// key는 'a' 값을 가지고 있는데, object에서의 'a'를 꺼내오기 위해 [key]를 사용했다.
// 그리고 다시 :a 로 변수 네이밍을 하였다.

타입스크립트를 사용할때 주의

  1. 당장 타입을 모르겠다면any 보단 unkown을! ... 그리고 추후에 type narrowing을 하자.
  2. instanceof, typeof 로 타입카드, in (객체의 키 확인)로 key 확인

리액트에 제네릭 적용하기

// useState에 제네릭을 적용하기
function Component(){
	const [state, setState] = useState<string>('')
}

인덱스 시그니처 사용하기

type HelloType = {
	[key : string] : string
}

const hello: Hello = {
  hello: 'hello',
  hi:hi,
}

hello[hi] // hi
hello['안녕'] // undefined

객체의 키를 좁히는 다양한 방법

// record 사용하기
type HelloType = Record<'hello' | 'hi', string>

const hello: HelloType ={
  hello : 'hello',
  hi : 'hi'
}

// 타입을 이용한 인덱스 시그니처
type HelloType = { [key in 'hello' | 'hi']: string}

// 리터럴 타입으로 암묵적 타입 할당
const hello: Hello ={
  hello : 'hello',
  hi:'hi'
}

타입스크립트에서 Object.keys가 잘 안되는 이유

// 다음과 같은 오류가 뜨는 경우

Object.keys(hello).map((key)=>{
  // Element implicitly has an 'any' type because expression of type 'string'
  // can't be used to index type 'Hello'
  // No index signature with a parameter of type 'string' was found on type 'Hello'
  
  const value = hello[key]
  return value
})

원인 : Object.keys가 string[]을 반환하는데, 이 string은 hello의 인덱스 키 이기 때문에 접근할 수 없기 때문이다.

해결방법

// 1 - Object.keys(hello)를 as로 타입을 단언하는 방법
(Object.keys(hello) as Array<keyof Hello>).map((key)=>{
   const value = hello[key]
  return value
})

// 2 - 타입 가드 함수를 만드는 방법, 함수 자체의 타입을 만드는 방법
function keyOf<T extend Object>(obj: T): Array <typeof T>{
  return Array.from(Object.keys(obj)) as Array <keyof T>
}
  
Object.keys(hello).map((key)=>{
  const value = hello[key]
  return value
})

// 3 - 가져온 key를 단언하는 방법
Object.keys(hello).map(key)=>{
  const value = hello[key as keyof Hello]
  return value
}

느낀점

이번 챕터에선 본격적으로 리액트에 들어가기전에 알아야 하는 기본 개념인 자바스크립트와 타입스크립트에 대한 내용을 다루었다. 처음엔, 알던 내용이라 빠르게 읽거나 넘겨도 되지 않을까 싶었다. 하지만 읽다보니 이전에 자바스크립트 딥다이브 책에서 보았으나, 가볍게 읽고 넘어갔던 헷깔렸던 개념. 그렇지만 리액트에서 중요한 개념이 있어 많은 도움이 된 것 같다.
확실히 중요한 개념은 반복학습을 하는 만큼 전에는 이해하지 못했던 것들을 이해할 수 있는 것 같다.
이 전 타입스크립트를 제대로 사용해 보지않고 '러닝 타입스크립트' 책을 빠르게 읽었을때와는 다르게 '한모금' 프로젝트에서 타입스크립트를 사용한 후 이번 내용을 읽어보니, 어려웠던점이나 헷깔렸던 점에 대해 공감이가고 한번 더 짚어줘서 도움이 된 것 같다.
책에는 많은 글자들이 있는데 그 글자 하나하나의 설명이 이해하기 쉬우면서 중요한 내용을 다루어서 꼭꼭 씹어서 읽고싶은 책인것 같다. 천천히 꾸준히 잘 읽어야겠다.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.