Skip to content

JuTiger-Lee/Design-Patterns

Repository files navigation

객체지향의 기초

  • 추상화
  • 캡슐화
  • 다형성
  • 상속

객체지향의 원칙

  • 바뀌는 부분은 캡슐화한다.
  • 상속보다는 구성을 활용한다.
  • 구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다.

인터페이스?

  • 인터페이스라고해서 클래스를 선언하는 부분에서 implements 키워드를 써서 어떤 자바 인터페이스를 구현하는 클래스를 만든는게 아니다.
  • 일반적으로 어떤 상위 형식(클래스, 인터페이스 등)에 있는 메소드를 구현하는 구상 클래스는 그 상위 형식의 인터페이스를 구현하는 클래스라고 생각하면 된다.

디자인 원칙

  1. 애플리케이션에서 달라지는 부분을 찾아 내고, 달라지지 않는 부분으로부터 분리 시킨다.
  • 달라지는 부분을 찾아서 나머지 코드에 영향을 주지 않도록 "캡슐화" 한다.
  • 그러면 코드를 변경하는 과정에서 의도하지 않은 일이 일어나는 것을 줄이면서 시스템의 유연성은 향상시킬 수 있다.
  1. 구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다.
  • 실제 실행시에 쓰이는 객체가 코드에 의해서 고정되지 않도록, 어떤 상위(supertype)에 맞춰서 프로그래밍함으로써 다형성을 활용해야한다.
  1. 서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 디자인을 사용해야 한다.
  • 느슨하게 결합하는 디자인을 사용하면 변경 사항이 생겨도 무난히 처리할 수 있는 유연한 객체지향 시스템을 구축할 수 있다.
  • 객체 사이의 상호의존성을 최소화할 수 있기 때문이다.
  1. OCP(Open-Closed Principle)
  • 클래스는 확장에 대해서는 열려있어야 하지만 코드 변경에 대해서는 닫혀있어야 한다.
  • 이 규칙을 잘 지키면 급변하는 주변 환경에 잘 적응할 수 있으면서도 강하고 튼튼한 디자인을 만들 수 있다.
  1. DIP(Dependency Inversion Principle) 의존성 뒤집기 원칙
  • 추상화된 것에 의존하도록 만들어야한다.
  • 구상 클래스에 의존하도록 만들지 않도록 한다.
  • 이 원칙은 고수준 구성요소가 저수준 구성요소에 의존하면 안 된다는 것이 내포되어있다.
  1. 추상화된 것에 의존하라
  • 추상화된 것에 의존하라, 구상 클래스에 의존하지 않도록 한다.

DIP 가이드 라인

  1. 어떤 변수에도 구상 클래스에 대한 레퍼런스를 저장하지 말아야 한다.
  • new 연산자를 사용하면 구상 클래스에 대한 레퍼런스를 사용하게되는 것이다.
  • 팩토리를 써서 구상 클래스에 대한 레퍼런스를 변수에 저장하는 일을 미리 방지한다.
  1. 구상 클래스에서 유도된 클래스를 만들지 말아야 한다.
  • 구상 클래스에서 유도된 클래스를 만들면 특정 구상 클래스에 의존하게 된다.
  • 인터페이스나 추상 클래스처럼 추상화된 것으로부터 클래스를 만들어야 한다.
  1. 베이스 클래스에 이미 구현되어있던 메소드를 오버라이드하지 말아야 한다.
  • 이미 구현되어있는 메소드를 오버라이드 한다는 것은 애초부터 베이스 클래스가 제대로 추상화 될 것이 아니었다고 볼 수 있다.
  • 베이스 클래스에서 메소드를 정의할 때는 모든 서브 클래스에서 공유할 수 있는 것만 정의해야 한다.

데메테르의 법칙(디미터 법칙) & 최소 지식 원칙

  • 정말 친한 치구하고 얘기하고, 낯선이에게 메세지를 말하지 마라
  • 데메테르의 법칙은 간단하게 의존성을 줄이는 것이다.
// 원칙을 따르지 않는 경우
class Test {
    public float getTemp() {
        Thermometer thermometer = sation.getThermometer();
        return thermometer.getTemperature();
    }
}

// 원칙을 따른 경우
class Test2 {
     public float getTemp() {
        return station.getTemperature();
    }
}
  • 첫번 쨰는 의존하는 클래스 객체를 두개를 의존한다. 만약에 thermometer가 바뀌게 되는 경우 Test Class 또한 변하겐된다.
  • 두번 째는 의존하는 클래스 객체가 한개이며 원칙을 잘 지킨 케이스이다.

메서드 호출 가이드 라인

  • 객체 자체의 메서드들
  • 메서드에 매개변수로 전달된 객체
  • 그 메서드에 생성하거나 인스턴스를 만든 객체
  • 그 객체에 구성하는 구성요소
public class Car {
    // 구성 요소의 메서드는 호출 가능
    Engine engine;

    public Car() {
        // 엔진 초기화 등을 처리
    }

    public void start(key Key) {
        // 새로운 객체를 생성 이 객체의 메서드를 호출 가능
        Doors doors = new Doors();
        // 매개변수로 전달된 객체의 메서드 호출 가능
        boolean authorized = key.turnes();

        if(authorized) {
            // 객체의 구성요소의 메서드는 호출 가능
            engine.start();
            // 객체 내에 있는 메서드는 호출 가능
            updateDashboardDisplay();
            // 인스턴스를 만든 객체의 메서드는 호출 가능
            doors.lock();
        }
    }

    public void updateDashboardDisplay() {
        // 디스플레이 갱신
    }
}
  • Java의 System.out.println 데메테르의 법칙에 어긋난다.

헐리우드 원칙

  • "먼저 연락하지 마세요. 저희가 연락 드리겠습니다."
  • 고수준 구성요소가 저수준 구성요소에 의존하고 그 저수준 구성요소가 다시 고수준 구성요소에 의존하면서 "의존성 부패(dependency rot)"가 발생한다.
  • 헐리우드 원칙을 활용하면 해당 의존성 부패를 방지가 가능하다.
  • 즉 고수준 구성요소에서 저수준 구성요소에게 "먼저 연락하지 말아라, 제가 먼저 연락 드리겠다"라고 얘기하는 것과 같다.
  • 사실 저수준 구성요소에서도 상속 계층구조상 위에 있는 클래스에서 정의한 메서드를 상속을 통해서 호출하게되는 경우가 빈번하지만 저수준과 고수준 사이에 확연하게 드러나는 순환 의존성이 생기는 것은 파하는게 좋다.

단일 역할 원칙

  • "클래스를 바꾸는 이유는 한 가지 뿐이어야 한다."
  • 어떤 클래스에서 맡고 있는 모든 역할들은 나중에 코드 변화를 불러올 수 있다.
  • 역할이 두개 이상 있으면 바뀔 수 있는 부분이 두가지 이상이 되는 것이다.
  • 해당 원칙에 따라 한 클래스에서는 한 가지 역할만 맡도록 해야 한다.

응집도

  • 한 클래스 또는 모듈이 특정 목적 또는 역할을 얼마나 일관되게 지원하는지를 나타내는 척도라고 할 수 있다.
  • 어떤 모듈 또는 클래스의 응집도가 높다는 것은 이련의 서로 연관되어 기능이 묶여있다는 것
  • 응집도가 낮다는 것은 서로 상관 없는 기능들이 묶여있다는 것을 뜻한다.

Detail

  • 즉 코드에 새로운 요구사항이 있을 때 마다 바뀌는 부분이 있다면 그 행동을 바뀌지 않는 다른 부분으로부터 골라내서 분리해야 한다.
  • 정리 => 바뀌는 부분은 따로 뽑아서 캡슐화, 그렇게하면 나중에 바뀌지 않는 부분에는
  • 영향을 미치지 않은 채로 그 부분만 고치거나 확장할 수 있다.

모든 패턴은 시스템의 일부분을 다른 부분과 독립적으로 변환 시킬 수 있는 방법을 제공하기 위한것이다.

About

객체지향 디자인 패턴

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published