각 모듈의 세분화된 역할이나 모듈들 간의 인터페이스와 같은 코드를 작성하는 수준의 세부적인 구현 방안을 설계할 때 참조할 수 있는 전형적인 해결 방식 또는 예제
GoF(Gang of Four) 디자인 패턴 : 유형에 따라 생성 패턴 5개, 구조 패턴 7개, 행위 패턴 11개 총 23개의 패턴으로 구성된다.
객체의 생성과 관련된 패턴으로, 객체의 생성과 참조 과정을 캡슐화하여 객체가 생성되거나 변경되어도 프로그램의 구조에 영향을 크게 받지 않도록 하여 프로그램에 유연성을 높여 준다.
ex) DBConnection을 관리하는 Instance를 하나만 만들 수 있도록 제한하여, 불필요한 연결을 막음
Abstract Factory(추상 팩토리)
Builder(빌더)
Factory Method(팩토리 메소드)
Prototype(프로토타입)
Singleton(싱글톤)
애플리케이션이 시작될 때, 어떤 클래스가 최초 한 번만 메모리를 할당하고 해당 메모리에 인스턴스를 만들어 사용하는 패턴
💡 인스턴스가 필요할 때, 똑같은 인스턴스를 만들지 않고 기존의 인스턴스를 활용하는 것
클래스나 객체들을 조합하여 더 큰 구조로 만들 수 있게 해주는 패턴
ex) 2개의 인터페이스가 서로 호환이 되지 않을 때, 둘을 연결해주기 위해서 새로운 클래스를 만들어서 연결 시킬 수 있도록 함
클래스를 바로 사용할 수 없는 경우가 있음 (다른 곳에서 개발했다거나, 수정할 수 없을 때) 중간에서 변환 역할을 해주는 클래스가 필요 → 어댑터 패턴
사용 방법 : 상속
호환되지 않은 인터페이스를 사용하는 클라이언트 그대로 활용 가능
향후 인터페이스가 바뀌더라도, 변경 내역은 어댑터에 캡슐화 되므로 클라이언트 바뀔 필요X
[클래스 다이어그램]
아이폰의 이어폰을 생각해보자
가장 흔한 이어폰 잭을 아이폰에 사용하려면, 잭 자체가 맞지 않는다.
따라서 우리는 어댑터를 따로 구매해서 연결해야 이런 이어폰들을 사용할 수 있다
⇒ 어댑터는 필요로 하는 인터페이스로 바꿔주는 역할
코드로 어댑터 패턴 이해하기
오리와 칠면조 인터페이스 생성
만약 오리 객체가 부족해서 칠면조 객체를 대신 사용해야 한다면?
두 객체는 인터페이스가 다르므로, 바로 칠면조 객체를 사용하는 것은 불가능함
따라서 칠면조 어댑터를 생성해서 활용해야 한다
package AdapterPattern;
public interface Duck {
public void quack();
public void fly();
}
package AdapterPattern;
public interface Turkey {
public void gobble();
public void fly();
}
```
- **WildTurkey.java**
```java
package AdapterPattern;
public class WildTurkey implements Turkey {
@Override
public void gobble() {
System.out.println("Gobble gobble");
}
@Override
public void fly() {
System.out.println("I'm flying a short distance");
}
}
package AdapterPattern;
public class TurkeyAdapter implements Duck {
Turkey turkey;
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
@Override
public void quack() {
turkey.gobble();
}
@Override
public void fly() {
turkey.fly();
}
}
package AdapterPattern;
public class DuckTest {
public static void main(String[] args) {
MallardDuck duck = new MallardDuck();
WildTurkey turkey = new WildTurkey();
Duck turkeyAdapter = new TurkeyAdapter(turkey);
System.out.println("The turkey says...");
turkey.gobble();
turkey.fly();
System.out.println("The Duck says...");
testDuck(duck);
System.out.println("The TurkeyAdapter says...");
testDuck(turkeyAdapter);
}
public static void testDuck(Duck duck) {
duck.quack();
duck.fly();
}
}
클래스나 객체들이 서로 상호 작용하는 방법이나 책임 분배 방법을 정의하는 패턴
ex) 하위 클래스에서 구현해야 하는 함수 및 알고리즘들을 미리 선언하여, 상속 시 이를 필수로 구현하도록 함