Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

README.md

객체지향 사고 프로세스(프로그래밍보다 먼저 익혀야 하는 생각의 기술)

  • 맷 와이스펠드 저/박진수 역 | 제이펍

1. 객체지향 개념 소개

  • 객체 래퍼(object wrappers) : 다른 코드를 둘러싸는 객체지향 코드
  • 객체에는 속성을 나타내는데 사용되는 정수 및 문자열과 같은 엔터디(entites)가 들어 있지만, 행위를 나타내는 메서드(methods)도 들어 있다.
  • 클래스란 객체를 만드는 템플릿이다.
  • 인터페이스는 클래스 사용자가 클래스와 상호 작용하는 방식을 완전히 설명해야 한다.
  • 클래스 다이어 그램에서 더하기 부호는 공개(public)를 나타내고 빼기 부호는 비공개(private)를 나타낸다.
  • 서브클래스가 슈퍼클래스로부터 상속을 받으면 슈퍼클래스가 할 수 있는 모든 것을 할 수 있다.
  • 다형성(polymorphism) : 비슷한 객체가 다른 방식으로 동일한 메시지에 응답 할 수 있음을 의미한다.

2. 객체라는 관점에서 생각하는 방법

  • 인터페이스와 구현부의 차이점을 아는 것
  • 더 추상적으로 생각하기
  • 사용자에게 가능한 한 인터페이스를 적게 제공하기
  • 구현부를 변경할지라도 사용자는 자신의 코드를 변경하지 않아도 되게 해야 한다.
  • 객체 지속성(object persistence)은 나중에 복원하고 사용할 수 있도록 객체의 상태를 저장하는 개념을 말한다.(지속되지 않는 객체는 기본적으로 범위(scope)를 벗어나면 사라지고 만다.)

3. 그 밖의 객체지향 개념들

  • 메서드의 시그니처(매개변수 목록)가 매번 다르면 오버로딩을 통해 프로그래머는 동일한 메서드 이름을 계속해서 사용할 수 있다.
  • 상속을 사용할 때 부모에 관한 모든 것을 상속한다.
  • 클래스의 static으로 선언한 변수는 인스턴스화된 모든 객체에 대해 단일한 메모리가 이 변수에 할당된다.

5. 클래스 설계 지침

  • 객체지향 방식은, 데이터와 행위가 논리적으로 별개의 객체가 되게 하는 구조적 방식이나 하향식 방식을 사용하는 대신에, 데이터와 행위가 서로 상호 작용할 수 있게 한 객체 안에 두어 캡슐화한다.
  • 최소한의 공개 인터페이스를 유지하도록 한다.
  • 생성자 주입(constructor injection) : 서비스 클래스를 클래스 내에 두는게 아니라 (생성자를 통해) 객체를 생성할 때(new 키워드를 사용해) 생성자에 주입한다는 것을 의미한다.
  • 객체는 다른 시스템에서 재사용할 수 있으며, 재사용을 염두에 두고 코드를 작성해야 한다.
  • 정적 메서드를 사용하게 되면 클래스들끼리 서로 강력하게 묶이게 된다.
  • 모든 코드를 한 번에 작성하지 말아야 한다. 코드 크기를 작게 해서 작성한 다음에 각 단계별로 코드를 빌드하고 테스트하자.

6. 객체를 사용해 설계하기

  • 견고한 객체지향 설계 과정에 포함되어야 하는 단계들
    • 적절한 분석 수행
    • 시스템을 설명하는 작업명세서 개발
    • 이 작업명세서로(시스템을 설명하는 문서)부터 요구사항을 수집
    • 사용자 인터페이스용 프로토타입 개발
    • 클래스 식별
    • 각 클래스의 역할을 결정
    • 다양한 클래스가 서로 상호 작용하는 방식을 결정
    • 만들고자 하는 시스템을 설명하는 고급 모델을 구성

7. 상속과 합성에 익숙해지기

  • 상속으로 인해 그 밖의 클래스에 대해서는 강력하게 캡슐화 할 수 있지만, 정작 슈퍼클래스와 서브클래스 사이의 캡슐화는 약해질 수 있다.
  • 합성과 상속을 상황에 맞게 적절히 섞어 써야한다.

8. 프레임워크 및 재사용 : 인터페이스와 추상 클래스를 사용해 설계하기

  • 추상 클래스는 추상 메서드와 구상 메서드를 모두 제공 할 수 있지만, 인터페이스는 추상 메서드만 제공할 수 있다.
  • 엄격한 상속 관계가 필요할 때는 추상 클래스를, 그렇지 않을 경우에는 인터페이스를 사용한다.
  • 인터페이스는 계약이다.

9. 객체 구축과 객체지향 설계

  • 합성을 사용하는 이유는 더 단순한 부품(components)을 하나로 묶어서 시스템을 구축할 수 있기 때문이다.
  • 응집 : 복합 객체가 그 밖의 객체들로 구성되어 있음을 의미한다.
  • 결합 : 응집은 일반적으로 전체만 보는 관계를 나타내는 반면, 결합은 전체와 부분을 모두 나타낸다. 그러나 실제로는 이 둘을 구분하기는 힘들다...
  • 합성을 사용할 때 객체를 서로 의존하지 않게 하는 편이 바람직하다.

10. 디자인 패턴

  • MVC 는 훌륭한 디자인이지만, 선행 디자인에 많은 주의를 기울여야 한다는 점에서 다소 복잡 할 수 있다.
  • 생성 패턴 : 객체를 직접 인스턴스화하지 않은 채로 객체를 만든다. 이를 통해 특정 사례에 대해 어떤 객체를 생성해야 할지 결정할 때 프로그램의 유연성이 향상된다.
    • 추상팩토리, 빌더, 팩토리 메서드, 프로토타입, 싱글톤
  • 구조 패턴 : 복잡한 사용자 인터페이스나 계정 데이터와 같은 객체 그룹을 더 큰 구조로 합성할 수 있다.
    • 어댑터, 브리지, 컴포지션, 데로레이터, 파사드, 플라이웨이트, 프록시
  • 행위 패턴 : 시스템의 객체 간 통신을 정의하고 복잡한 프로그램에서 흐름을 제어하는 방법을 정의한다.
    • 책임 연쇄, 커맨드, 인터프리터, 이터레이터, 미디에이터, 메멘토, 옵저버, 스테이트, 스트레테지, 템플릿 메서드, 비지터

11. 의존적이거나 경직된 클래스가 되지 않게 하기

  • 합성에서는 클래스 자체에 행위를 포함하지 않고 각 행위에 대해 개별 클래스를 만든다.
  • 의존성 주입 : 객체를 생성하는 대신에 매개변수 목록을 통해 다른 객체 내부로 외부 객체를 주입한다.

12. 객체지향 설계의 SOLID 원칙

  • SRP : 단일 책임 원칙(Single Responsibility Principle)
    • 클래스를 변경한 이유가 단일해야 한다.
    • 프로그램의 각 클래스와 모듈은 단일 작업에 중점을 두어야 한다.
    • 같은 클래스 안에 다른 이유 때문에 변경될 메서드를 넣지 않도록 한다.
  • OCP : 개방/폐쇄 원칙(Open/Close Principle)
    • 클래스를 수정하지 않고 클래스의 행위를 확장 할 수 있어야 한다.
  • LSP : 리스코프 대체 원칙(Liskov Substitution Principle)
    • 부모 클래스의 인스턴스를 해당 자식 클래스 중 하나의 인스턴스로 교체할 수 있게 설계해야 한다.
    • 부모 클래스가 무언가를 할 수 있다면 자식 클래스도 그것을 할 수 있어야 한다.
  • ISP : 인터페이스 분리 원칙(Interface Segregation Principle)
    • 몇 개의 큰 인터페이스가 있는 편보다는 작은 인터페이스가 많은 편이 바람직하다.
  • DIP : 의존성 역전 원칙(Dependency Inversion Principle)
    • 코드는 추상화에 의존해야 한다.
    • 의존성 역전 : 의존체들을 역전시키는 원칙
    • 의존성 주입 : 의존체들을 역전시키는 행위
    • 생성자 주입 : 생성자를 통해 의존성 주입을 수행
    • 파라미터 주입 : 세터과 같은 메서드의 파라미터를 통해 의존성 주입을 수행