개요 목적
디자인 패턴이란 프로그래밍 상황에서 발생하는 문제 패턴을 발견하고 해결 할 수 있는 패턴을 제시한 것이다.
Spring 백엔드를 공부하면 다양한 디자인 패턴으로 된 코드들을 만나게 된다. 그래서 자바 예시 코드들을 작성하면서 디자인 패턴의 모양과 특징에 대해서 알아보려 한다.
Proxy Pattern
프록시 패턴은 클라이언트가 사용하려고 하는 실제 객체인 것처럼 위장하여 클라이언트의 요청을 대신 처리한다.
프록시 객체 안에는 실제 클라이언트가 요청한 대상인 target이 있어서,
접근을 제어하며 target의 동작을 그대로 수행할 수 도 있고,
부가적 기능을 붙여서 요청을 처리할 수도 있다(Decorate Pattern).
//클라이언트는 해당 인터페이스만 알면 프록시를 적용할 수 있게 추상화 진행
public interface TargetInterface {
void run();
}
//클라이언트가 실제로 원하는 target
public class TargetImpl implements TargetInterface{
@Override
public void run() {
System.out.println("TargetImpl.run() 실행");
}
}
//타깃 오브젝트를 프록시에서 가지고 있는다
public class Proxy implements TargetInterface{
private final TargetInterface target;
public Proxy(TargetInterface target) {
this.target = target;
}
@Override
public void run() {
System.out.println("DecoratorProxy 시작"); //부가적인 기능을 부여
target.run(); //실제 타깃의 로직 실행
}
}
Composite Pattern
composite pattern은 객체들의 관계를 트리 구조로 구성하여 부분-전체 계층을 표현하는 패턴으로, 사용자가 단일 객체와 복합 객체 모두 동일하게 다루도록 한다.
public interface Shape {
public void draw(String fillColor);
}
public class Circle implements Shape {
@Override
public void draw(String fillColor) {
System.out.println("Drawing Triangle with color "+fillColor);
}
}
public class Triangle implements Shape {
@Override
public void draw(String fillColor) {
System.out.println("Drawing Triangle with color "+fillColor);
}
}
//클라이언트는 Shape를 구현한 Drawing 객체를 사용하면,
//단일 객체 복합 객체 구분 없이 공통된 로직을 다룰 수 있다
public class Drawing implements Shape{
private List<Shape> shapes = new ArrayList<>();
@Override
public void draw(String fillColor) {
for(Shape sh : shapes)
{
sh.draw(fillColor);
}
}
public void add(Shape s){
this.shapes.add(s);
}
public void remove(Shape s){
shapes.remove(s);
}
}
Adapter Pattern
adapter pattern은 서로 호환되지 않는 두 클래스를 연결되도록 만든다.
Interface Animal {
public void walk();
}
class Cat implements Animal {
@Override
public void walk() {
System.out.println("cat walking");
}
}
class Fish {
public void swim() {
System.out.println("fish Swimming");
}
}
//피시클래스와 애니멀 인터페이스를 연결해줄 피시 어댑터클래스를 구성
class FishAdapter implements Animal {
Fish fish;
FishAdapter(Fish fish) {
this.fish = fish;
}
@Override
public void walk() {
fish.swim();
}
}
Observer Pattern
observer pattern은 객체의 상태 변화를 감지하는 옵저버 목록에 객체를 등록하여 변화가 있을 때마다 메서드를 통해 알림을 각 객체에게 통지하는 디자인 패턴이다.
interface Observer {
void update();
}
class DogObserver implements Observer {
@Override
public void update() {
System.out.println("멍멍 울림");
}
}
class CatObserver implements Observer {
@Override
public void update() {
System.out.println("야옹 울림");
}
}
//옵저버 구현체들을 담을 수 있는 EventBox 구성
//한 곳에서 알림을 관리할 수 있다.
class EventBox {
List<Observer> list = new ArrayList<>();
void addObserver(Observer observer) {
list.add(observer);
}
void eventNotify() {
for (var observer : list) {
observer.update();
}
}
}
Strategy Pattern
strategy pattern은 객체에 수정이 있을 때 직접 수정하지 않고, 전략 패턴의 도움을 받아 외부에서 손쉽게 수정할 수 있도록 도와준다.
public interface AttackStrategy {
void attack();
}
public class MissileAttack implements AttackStrategy{
@Override
public void attack() {
System.out.println("missile attack");
}
}
public class PunchAttack implements AttackStrategy{
@Override
public void attack() {
System.out.println("punch attack");
}
}
public class Robot {
private AttackStrategy attackStrategy;
public void setAttackStrategy(AttackStrategy attackStrategy) {
this.attackStrategy = attackStrategy;
}
//attack 종류를 변경하고 싶을 때 내부적 코드를 변경하는 것이 아니라,
//외부에서 전략 변경을 통해 수정할 수 있다.
public void attack() {
attackStrategy.attack();
}
}
Template Method Pattern
template method pattern은 구성 요소 대부분은 동일하게 가져가지만 일부만 다를 때 중복을 최소화할 수 있는 패턴이다.
public abstract class BasicRecipe {
public void boilWater() {
System.out.println("물을 500ml 넣고 끓인다");
}
public void addRamen() {
System.out.println("기본 내용물을 넣는다.");
}
//나머지 부분은 공통 코드로 관리하고,
//특징을 주는 부분만 각 구현 클래스에서 구현할 수 있도록 설정
public abstract void addCharacter();
}
public class FishRamenRecipe extends BasicRecipe{
@Override
public void addCharacter() {
System.out.println("생선을 넣는다");
}
}
public class MeatRamenRecipe extends BasicRecipe{
@Override
public void addCharacter() {
System.out.println("고기를 넣는다");
}
}
Reference
https://live-everyday.tistory.com/240