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. 팩토리 메서드 패턴 예시

Phone 인터페이스

public interface Phone {
	void turnOn();
}

IPhone 클래스

public class IPhone implements Phone {
	@Override
	public void turnOn() {
		System.out.println("IPhone turn on");
	}
}

Galaxy 클래스

public class Galaxy implements Phone {
	@Override
	public void turnOn() {
		System.out.println("Galaxy turn on");
	}
}

PhoneFactory 클래스

public class PhoneFactory {
	public static Phone getPhone(String company) {
		if ("Apple".equalsIgnoreCase(company)) retrn new IPhone();
		else if ("Samsung".equalsIgnoreCase(company)) retrn new Galaxy();

		return null;
	}
}

getPhone 메서드를 이용하여 Phone의 서브클래스에 대한 정보를 알지 못한 채 인스턴스를 생성할 수 있게 된다.

 

Main 클래스

public class Main {
	public static void main(String[] args) {
		Phone iPhone = PhoneFactory.getPhone("Apple");
		Phone galaxy = PhoneFactory.getPhone("Samsung");

		iPhone.turnOn();
		galaxy.turnOn();
	}
}

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

'디자인 패턴 > 생성 패턴' 카테고리의 다른 글

싱글톤 패턴 (Singleton Pattern)  (0) 2021.08.26

1. 전략 패턴이란?

  • 실행 중에 알고리즘을 선택할 수 있게 하는 행위 소프트웨어 디자인 패턴
  • 특정한 계열의 알고리즘들을 정의하고 각 알고리즘을 캡슐화

 


 

2. 전략 패턴의 예시

아이폰은 애플스토어, 갤럭시는 구글플레이스토어(줄여서 플레이스토어)를 사용한다.
이를 이용해 간단한 예시를 만들어 보았다.

1) 전략 패턴을 적용하지 않은 경우

스토어 인터페이스

public interface Store {
	public void store();
}

아이폰 클래스

public class IPhone implements Store {
	public void store() {
		System.out.println("Appstore On");
	}
}

갤럭시 클래스

public class Galaxy implements Store {
	public void store() {
		System.out.println("PlayStore On");
	}
}

메인 클래스

public class Main {
	public static void main(String[] args) {
		Store iPhone = new IPhone();
		Store galaxy = new Galaxy();

		iPhone.store();
		galaxy.store();
	}
}

// 출력
// AppStore On
// PlayStore On

만약 애플에서 삼성을 인수하여, 이제 갤럭시에서도 애플스토어를 쓴다고 가정하자. 그렇게 되면 Galaxy의 store() 메서드를

System.out.println("AppStore On");

로 바꿔주면 되지만, 이는 개방 폐쇄의 원칙에 어긋나며, 확장이 될 경우 유지보수를 어렵게 한다. 따라서 이럴 경우 전략 패턴을 적용하면 문제를 해결할 수 있다.

 

2. 전략 패턴을 적용한 경우

스토어를 이용하는 두 가지 경우를 클래스로 생성하며, store()를 이용하여 어떤 스토어를 이용하는지 구현한다.

스토어 인터페이스

public interface Store {
	public void store();
}

앱스토어 클래스

public class AppStore implements Store {
	public void store() {
		System.out.println("AppStore On");
	}
}

플레이스토어 클래스

public class PlayStore implements Store {
	public void store() {
		System.out.println("PlayStore On");
	}
}

myStore 클래스

 

public class MyStore {
	private Store myStore;

	public void store() {
		myStore.store();
	}

	public void setStore(Store myStore) {
		this.myStore = myStore;
	}
}

IPhone, Galaxy 클래스

public class IPhone extends MyStore {

}

public class Galaxy extends MyStore {

}
이제 IPhone에서는 앱스토어를, Galaxy에서는 플레이스토어를 이용할 수 있도록 구현한다.

Main 클래스

public class Main {
	public static void main(String[] args) {
		MyStore iPhone = new IPhone();
		MyStore galaxy = new Galaxy();

		iPhone.setStore(new AppStore());
		galaxy.setStore(new PlayStore());
        
		iPhone.store();
		galaxy.store();
	}
}

아까 상황과 같이 애플이 삼성을 인수하여 갤럭시에서 앱스토어를 사용한다고 가정하면, setStore 메서드를 이용하여 수정하기만 하면 된다.

galaxy.setStore(new AppStore());
galaxy.store();

'디자인 패턴 > 행위 패턴' 카테고리의 다른 글

옵저버 패턴 (Observer Pattern)  (0) 2021.08.29

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

1. 싱글톤 패턴이란?

  • 전역 변수를 사용하지 않고 객체를 하나만 생성하도록 하는 패턴
  • 생성된 객체를 어디에서든지 참조될 수 있음
  • 인스턴스가 오직 1개만 생성되어야 하는 경우에 사용
  • private constructor와 static method를 사용

2. 싱글톤 패턴 예시

public class Book {
	private static Book book = null;
    
	private Book() {}
    
	public static Book getInstance() {
		if (book == null) {
			book = new Book();
		}
		return book;
	}
}

+ Recent posts