디자인 패턴이란?
코드를 재사용하는 것과 마찬가지로 경험을 재사용하는 것
객체지향 시스템 구축 방법들을 모아 놓은 것.

객체지향 디자인을 할 때 고민 해야 할 문제
1. 소프트웨어를 만들 때, 나중에 혹시 고쳐야 할 때도 기존 코드에 미치는 영향은 최소한으로 줄이면서작업을 할 수 있도록 만들 수 있는 방법을 고민 해야 함.
2. 자바 interface 에는 구현된 코드가 전혀 들어가지 않기 때문에 코드 재사용을 할 수 없다는 문제점이 있음.
3. 관리가 용이 하고 상황에 맞게 변경 할 수 있는 유연한 디자인을 만드는 것에 대해 생각 해봐야 함.
4. 나중에 어떻게 바뀔 것인지에 대해 생각해 보는 것

아래와 같은 SimDuck 이라는 애플리케이션이 있다.

오리들에게 날라 다닐수 있는 기능을 추가 해 달라는 요청이 들어왔다.

변경 사항 적용하기
1. 요청 사항을 반영하기 위해서 Duck 클래스 안에 fly() 를 추가하여 상속 받아서 사용 할 수 있도록 Duck 클래스를 수정 하였다.
   문제 발생 
   fly()를 상속을 받게 되어 있어서 날수 없는 모형 오리들도 나는 기능이 추가 되었다.
   해결 방안 
   오버라이드를 사용하여 날수 없는 오리들은 아무 기능도 하지 않도록 수정한다.
   -> 규격이 계속 변경이 될때마다 Duck의 서브클래스들의 fly()를 살펴보고 변경이 이루어져야 한다. 서브 클래스 마다 오리의 행동이 변경될 수 있는데 모든 서브클래스에서 한 행동을 사용하도록 하는것은 좋지 않다.

2. 인터페이스로 fly() 기능을 구현한다.
    문제 발생
    Duck의 서브클래스들이 많은 경우 중복된 코드가 많아져서 관리하기가 힘들다.

요구사항을 들어주기 위해서 문제를 명확하게 파악한 후 디자인 원칙을 사용하여 문제를 해결해 보자.
디자인 원칙
1. 애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분으로부터 분리 시킨다.
달라지는 부분을 찾아서 나머지 코드에 영향을 주지 않도록 "캡슐화" 합니다. 그러면 나중에 바뀌지 않는 부분에는 영향을 미치지 않은 채로 그부분만 고치거나 확장할 수 있다.

2. 구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.
    ->"상위 형식에 맞춰서 프로그래밍하라"
    -> 실제 실행시에 쓰이는 객체가 코드에 의해서 고정되지 않도록, 어떤 상위 형식(supertype)에 맞춰서
         프로그래밍함으로써 다형성을 활용해야 한다.
    ->변수를 선언할 때는 보통 추상 클래스나 인터페이스 같은 상위 형식으로 선언해야 한다. 객체를 변수에 대입할 때 
       상위 형식을 구체적으로 구현한 형식이라면 어떤 객체든 집어넣을 수 있기 때문이다. 그렇게 하면 변수를 선언하는 
       클래스에서 실제 객체의 형식을 몰라도 된다.

public abstract class Animal {
    abstract makeSound();
}

class Dog extends Animal {
    makeSound() {
        bark();
    }
}

구현에 맞춰서 프로그램밍한 예
Dog d = new Dog();
d.bark();
-> 변수 d를 Dog 형식으로 선언하면 언떤 구체적인 구현에 맞춰서 코딩을 해야만 합니다.

인터페이스/상위 형식에 맞춰서 프로그래밍 한 예
Animal a = new Dog();
a.makeSound();
-> Dog라는 걸 알고 있긴 하지만 다형성을 활용하여 Animal에 대한 레퍼런스를 써도 됩니다.

구체적으로 구현된 객체를 실행시 대입 한 예(제일 좋은 예)
a = getAnimal();
a.makeSound();
-> Animal의 하위 형식 가운데 어떤 형식인지는 모릅니다. 단지 makeSound() 에 대해 올바른 반응을 할 수만 있으면 됩니다.

상위 형식의 인터페이스를 정의한 후 그 행위에 필요한 실제 클래스를 구현한다.
그러면 다른 형식의 객체에서도 행위를 재사용 할 수 있다.

3. 상속보다는 구성을 활용한다.
A에는 B가 있다. 두 클래스를 이런 식으로 합치는 것을 구성(composition)을 이용하는 것이라고 부릅니다.


훌륭한 객체지향 디자인 이라면 재사용성, 확장성, 관리의 용이성을 가춰야 합니다.


스트래지 패턴(strategy pattern)

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

핵심정리
- 객체지향 기초지식만 가지고는 훌륭한 객체지향 디자이너가 될 수 없습니다.
- 훌륭한 객체지향 디자인이라면 재사용성, 확장성, 관리의 용이성을 갖춰야 합니다.
- 패턴은 훌륭한 객체지향 디자인 품질을 갖추고 있는 시스템을 만드는 방법을 제공해 줍니다.
- 패턴은 검증받은 객체지향 경험의 산물입니다.
- 패턴이 코드를 바로 제공해주는 것은 아닙니다. 디자인문제에 대한 일반적인 해법을 제공해주죠. 특정 애플리케이션에 패턴을 적용하는 것은 여러분이 해야 할 일입니다.
- 패턴은 발명되는 것이 아니라 발견되는 것입니다.
- 대부분의 패턴과 원칙은 소프트웨어의 변경 문제와 관련되어 있습니다.
- 많은 경우에 시스템에서 바뀌는 부분을 골라내서 캡슐화시켜야 합니다.
- 패턴은 다른 개발자들과의 의사소통의 가치를 극대화시킬 수 있는 전문 용어 역할을 합니다.


자바 관련 내용
추상화, 캡슐화, 다형성, 상속

Posted by outliers
,