객체지향의 기초 
추상화 , 캡슐화 , 다형성 , 상속

객체지향의 원칙 

  • 바뀌는 부분을 캡슐화한다.
  • 상속보다는 구성을 활용한다.
  • 구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.
  • 서로 상호작용을 하는 객체사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.
  • OCP(Open-closed Principle) : 클래스는 확장에 대해서는 열려있어야 하지만, 코드 변경에 대해서는 닫혀 있어야 한다.
  • 추상화된 것에 의존하라. 구상 클래스에 의존하지 않는다.
  • 친한친구들하고만 이야기한다.
  • 먼저 연락하지 마세요. 저희가 연락 드리겠습니다.
  • 클래스를 바꾸는 이유는 한 가지 뿐이어야 한다.

디자인 원칙

  • 애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분으로부터 분리시킨다.(인터페이스와 구현부의 분리) 
    : 달라지는 부분을 찾아서 나머지 코드에 영향을 주지 않도록 캡슐화합니다. 그러면 코드를 변경하는 과정에서 의도하지 않은 일이 일어나는 것을 줄이면서 시스템의 유연성은 향상시킬 수 있습니다. 
  • 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.
  • 추상화된 것에 의존하도록 만들어라. 구상 클래스에 의존하도록 만들지 않도록 한다.
  • 최소 지식의 원칙 : 정말 친한 친구하고만 얘기하라
  • 객체지향 프로그래밍에서는 친구가 하나만 있는 것이 좋습니다.
  • 구현이 아닌 인터페이스에 맞춰서 프로그래밍한다. 
    : 객체가 코드에 의해서 고정되지 않도록 , 어떤 상위 형식(supertype)에 맞춰서 프로그래밍함으로써 다형성을 활용해야 한다. 구체적으로 구현된 객체는 실행시에 대입하는 것 -> 상속을 쓸때 떠안게 되는 부담을 전부 떨쳐 버리고도 재사용성의 장점을 그대로 누릴 수 있습니다.

전문용어의 위력

  • 서로 알고 있는 패턴 용어는 정말 막강합니다.
  • 패턴을 이용하면 간단한 단어로 많은 것을 얘기할 수 있습니다.
  • 패턴수준에서 이야기를 하면 디자인에 더 오랫동안 집중할 수 있습니다.
  • 전문용어를 사용하면 개발 팀의 능력을 극대화할 수 있습니다.
  • 전문용어는 신참개발자에게 훌륭한 자극제가 됩니다.

    객체지향 패턴 
    스트래티지 패턴(strategy pattern) : 알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다. 스트래티지를 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수가 있다.

    옵저버 패턴(Observer Pattern) : 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신이 되는 방식으로 일대다(one-to-many) 의존성을 정의합니다.
    ex) java.util.Observable

    데코레이터 패턴(Decorator Pattern) :  객체에 추가 요소를 동적으로 더할 수 있습니다. 데코레이터를 사용하면 서브 클래스를 만드는 경우에 비해 훨씬 유연하게 기능을 확장할 수 있습니다 .
    ex) java.io에 관련된 클래스들

    팩토리 메소드 패턴(Factory Method Pattern) : 팩토리 메소드 패턴에서는 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 됩니다. 팩토리 메소드 패턴을 이용하면, 클래스의 인스턴스를 만드는 일을 서브클래스에게 맡기는 것

    추상팩토리 패턴(Abstract Factory Pattern) : 추상 팩토리 패턴에서는 인터페이스를 이용하여 서로 연관된, 또는 의존하는 객체를 구상클래스를 지정하지 않고도 생성할 수 있습니다.

    싱글턴 패턴(singleton pattern) : 해당 클래스의 인스턴스가 하나만 만들어지고, 어디서든지 인스턴스에 접근할 수 있도록 하기 위한 패턴입니다.

    커맨드 패턴(Command Pattern) : 커맨드 패턴을 이용하면 요구사항을 객체로 캡슐화 할 수 있으며, 매개변수를 써서 여러가지 다른 요구 사항을 집어 넣을 수도 있습니다. 또한 요청 내역을 큐에 저장하거나 로그로 기록할 수도 있으며, 작업취소 기능도 지원합니다.

    어댑터 패턴(Adapter Pattern) : 한 클래스의 인터페이스를 클라이언트엗서 사용하고자 하는 다른 인터페이스로 변화합니다. 어댑터를 이용하면 인터페이스 호환성 문제때문에 같이 쓸수 없는 클래스들을 연결해서 쓸수가 있습니다.

    퍼사드 패턴(Facade Pattern) : 어떤 시스템의 일련의 인터페이스에 대한 통합된 인터페이스를 제공합니다. 퍼사드에서 고수준 인터페이스를 정의하기때문에 서브시스템을 더 쉽게 사용할 수 있습니다.

    템플릿 메소드 패턴(Template Method Pattern) : 메소드에서 알고리즘의 골격을 정의합니다. 알고리즘의 여러 단계중 일부는 서브클래스에서 구현할 수 있습니다. 템플릿 메소드를 이용하면 알고리즘의 구조는 그대로 유지하면서 서브클래스에서 특정 단계를 재정의할 수 있습니다.
    ex)  알고리즘의 틀을 만들기 위한 패턴 

    이터레이터 패턴(Iterator Pattern) : 컬렉션 구현 방법을 노출시키지 않으면서도 그 집합체 안에 들어있는 모든 항목에 접근할 수 있게 해주는 방법을 제공해 줍니다.

    컴포지트 패턴(Composite Pattern) : 객체들을 트리구조로 구성하여 부분과 전체를 나타내는 구조로 만들 수 있습니다. 이 패턴을 이용하면 클라이언트에서 개별 객체와 다른 객체들로 구성된 복합 객체(Composite)를 똑같은 방법으로 다룰수 있습니다.

    • 컴포지트 패턴이 클라이언트가 보기에 투명하게 작동하려면 복합 객체 내에 있는 모든 객체들의 인터페이스가 똑같아야 합니다. 인터페이스를 통일시키다가 보면 객체에 따라 아무 의미가 없는 메소드도 생길 수 있습니다.
      의미없는 메소드의 처리 방법
      1. 아무일도 하지 않거나 널 또는 false를 상황에 맞게 리턴하는 방법
      2. 예외를 던지는 방법

    스테이트 패턴(State Pattern) : 객체의 내부 상태가 바뀜에 따라서 객체의 행동을 바꿀수 있습니다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있습니다.

    • 객체에 수많은 조건문을 집어넣는 대신에 사용할 수 있는 패턴

    프록시 패턴(Proxy Pattern) : 어떤 객체에 접근을 제어하기 위한 용도로 대리인이나 대변인에 해당하는 객체를 제공하는 패턴

    의존성 뒤집기 원칙에 위배되는 객체지향 디자인을 피하는데 도움이 되는 가이드 라인

    • 어떤 변수에도 구상 클래스에 대한 레퍼런스를 저장하지 맙시다
    • 구상 클래스에서 유도된 클래스를 만들지 맙시다.
    • 베이스 클래스에 이미 구현되어 있던 메소드를 오버라이드하지 맙시다.

    감상문 : OOP의 가장 이상적인 모델
    인터페이스로 통신 및 접근을 하고, 구현체는 추상화되어 있어서 인터페이스 기반으로 설계를 한다. 객체를 생성하는 코드를 남발하지 않고, 한군데서 관리하도록 한다. 
    강력한 추상화,캡술화만이 OOP를 잘하는 지름길이다.

  • [출처 : http://www.ologist.co.kr/266]

    + Recent posts