1. 데코레이터 패턴이란?

  • 객체의 결합을 통해 기능을 동적으로 유연하게 확장할 수 있게 해주는 패턴
  • 추가 기능의 조합을 설계하는 패턴

 


 

2. 데코레이터 패턴 예시

IPhone 시리즈 중 IPhoneSE는 500달러, IPhoneMini는 400달러라고 가정하자(또한 기본 시리즈를 iPhone이며, 이는 300달러라고 가정). 다음 예시는 Decorator 패턴을 통해 두 시리즈의 가격을 알려주는 예시이다.

Phone 인터페이스

public interface Phone {
	public void showPrice();
}

IPhone 클래스

public class IPhone implements Phone {
	public int price;
    
	public IPhone(int price) { this.price = price; }

	@Override
	public void showPrice() {
		System.out.println("iPhone: $" + this.price);
	}
}

IPhone을 꾸며주는 IPhoneDecorator

public class IPhoneDecorator implements Phone {
	public Phone iPhone;
	public String name;
	public int price;

	public IPhoneDecorator(Phone iPhone, String name, int price) {
		this.iPhone = iPhone;
		this.name = name;
		this.price = price;
	}

	@Override
	public void showPrice() {
		System.out.println(name + ": $" + this.price);
	}
}

IPhoneDecorator를 상속받는 IPhoneSE, IPhoneMini 클래스

public class IPhoneSE extends IPhoneDecorator {
	public IPhoneSE(Phone iPhone, String name) {
		super(iPhone, name, 500);
	}
}

public class IPhoneMini extends IPhoneDecorator {
	public IPhoneMini(Phone iPhone, String name) {
		super(iPhone, name, 400);
	}
}

Main 클래스

public class Main {
	public static void main(String[] args) {
		Phone iPhone = new IPhone(300);
		iPhone.showPrice();
	
		// iPhoneSE
		Phone iPhoneSE = new IPhoneSE(iPhone, "iPhoneSE");
		iPhoneSE.showPrice();
		
		// iPhoneMini
		Phone iPhoneMini = new IPhoneMini(iPhone, "iPhoneMini");
		iPhoneMini.showPrice();
	}
}

// 출력
// iPhone: $300
// iPhoneSE: $500
// iPhoneMini: $400

 

'디자인 패턴 > 구조 패턴' 카테고리의 다른 글

프록시 패턴 (Proxy Pattern)  (0) 2021.08.28
파사드 패턴 (Facade Pattern)  (0) 2021.08.27
어댑터 패턴 (Adapter Pattern)  (0) 2021.08.26

1. 프록시 패턴이란?

  • 실제 기능을 수행하는 객체 대신 가상의 객체를 사용해 로직의 흐름을 제어
  • 어떤 객체를 사용하고자 할 때 해당 객체를 대행하는 객체를 통해 대상 객체에 접근
  • 흐름제어만 할 뿐 결과값을 조작하거나 변경시키면 안됨

 


 

2. 프록시 패턴 예시

Phone 인터페이스

public interface Phone {
	public String turnOn();
}

IPhone 클래스

public class IPhone implements Phone {
	@Override
	public String turnOn() {
		return "IPhone turn on";
	}
}

PhoneProxy 클래스

public class PhoneProxy implements Phone {
	Phone iPhone;

	@Override
	public String turnOn() {
		System.out.println("Proxy 거쳐감");

		iPhone = new IPhone();
		return iPhone.turnOn();
	}
}

Main 클래스

public class Main {
	public static void main(String[] args) {
		Phone proxy = new PhoneProxy();
		System.out.println(proxy.turnOn());
	}
}

// 출력
// Proxy 거쳐감
// IPhone turn on

 

인터페이스를 중간에 두어 구체클래스들에게 영향을 받지 않게 설계하였으며, 직접 접근하지 않고 Proxy를 통해 한번 더 우회해서 접근하도록 구현되어 있다. 이를 통해 OCP, DIP 설계 원칙을 지킬 수 있다.

1. 파사드 패턴이란?

  • 소프트웨어의 다른 코드 부분에 대하여 간략화된 인터페이스를 제공
  • 퍼사드 객체는 복잡한 소프트웨어 바깥쪽의 코드가 라이브러리의 안쪽 코드에 의존하는 일을 감소시킴

 


 

2. 파사드 패턴의 예시

1. IPhone 클래스

public class IPhone {
	public void powerOn() {
		System.out.println("IPhone turn on");
	}
}

2. Galaxy 클래스

public class Galaxy {
	public void powerOn() {
		System.out.println("Galaxy turn on");
	}
}

3. PhoneFacade 클래스

public class PhoneFacade {
	private IPhone iPhone;
	private Galaxy galaxy;
    
	public PhoneFacade() {
		iPhone = new IPhone();
		galaxy = new Galaxy();
	}
    
	public void turnOn() {
		iPhone.powerOn();
		Galaxy.powerOn();
	}
}

4. Main 클래스

public class Main {
	public static void main(String[] args) {
		PhoneFacade phoneFacade = new PhoneFacade();
		phoneFacade.turnOn();
	}
}

// 출력
// IPhone turn on
// Galaxy turn on

 

PhoneFacade는 IPhone과 Galaxy를 캡슐화하여 turnOn() 메서드만 이용할 수 있고, 그 내부의 모습은 알 수 없다. 이 때, IPhone, Galaxy 객체를 생성하여 각자 powerOn() 메서드를 실행시키는 것이 아닌, PhoneFacade 클래스의 turnOn() 메서드를 통해 powerOn() 메서드를 실행시킨다.

1. 어댑터 패턴이란?

  • 클래스의 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하는 패턴
  • 호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 작동하도록 해줌

2. 어댑터 패턴 예시

// 갤럭시폰 인터페이스
public interface Galaxy {
	public void Samsung();
}

// 갤럭시노트 클래스
public class GalaxyNote implements Galaxy {
	@Override
	public void Samsung() {System.out.println("I'm from Samsung");
}


// 아이폰 인터페이스
public interface IPhone {
	public void Apple();
}

// 아이폰SE 클래스
public class IPhoneSE implements IPhone {
	@Override
	public void Samsung() {System.out.println("I'm from Apple");
}

 

여기서 IPhone과 Galaxy를 연결해주는 어댑터를 생성한다.

// 어댑터 생성
public class IPhoneAdapter implements Galaxy {
	private IPhone iPhone;
    
	public IPhoneAdapter (IPhone iPhone) { this.iPhone = iPhone; }
    
	@Override
	public void Samsung() { iPhone.Apple(); }
}

 

이제 어댑터를 이용하여 메인 코드를 작성한다.

public class Main {
	public static void main(String[] args) {
		IPhoneSE iPhonSE = new IPhoneSE();
		// IPhonSE 인스턴스 생성
        
		GalaxyNote galaxyNote = new GalaxyNote();
		// GalaxyNote 인스턴스 생성
        
		Galaxy iPhoneAdapter = new IPhoneAdapter(galaxyNote);
        
		testGalaxy(galaxyNote);
		testGalaxy(iPhoneAdapter);
	}
    
	public static void testGalaxy(Galaxy galaxy) {
		galaxy.Samsung();
	}
}

'디자인 패턴 > 구조 패턴' 카테고리의 다른 글

데코레이터 패턴 (Decorator Pattern)  (0) 2021.08.29
프록시 패턴 (Proxy Pattern)  (0) 2021.08.28
파사드 패턴 (Facade Pattern)  (0) 2021.08.27

+ Recent posts