어댑터 패턴
전력 공급 장치의 인터페이스를 조정하는 패턴입니다. 예를 들어, 두 개의 전극을 가진 전원 케이블이 세 개의 전극을 지원하는 기기와 호환되지 않을 때, 이 패턴은 두 가지 인터페이스 간의 호환성을 해결합니다.
1. 세 개 전극 인터페이스 정의
public interface ThreePhasePower {
void supplyThreePhase();
}
2. 세 개 전극 구현 클래스
public class ThreePhase implements ThreePhasePower {
public void supplyThreePhase() {
System.out.println("세 개 전극으로 전원 공급\n");
}
}
3. 두 개 전극 클래스
public class TwoPhase {
public void supplyTwoPhase() {
System.out.println("두 개 전극으로 전원 공급");
}
}
4. 인터페이스 변환 어댑터
public class TwoToThreeAdapter implements ThreePhasePower {
private final TwoPhase two;
public TwoToThreeAdapter(TwoPhase two) {
this.two = two;
}
public void supplyThreePhase() {
System.out.println("인터페이스 변환 수행");
two.supplyTwoPhase();
}
}
5. 상속 기반 어댑터
public class InheritanceAdapter extends TwoPhase implements ThreePhasePower {
public void supplyThreePhase() {
System.out.println("\n상속 기반 변환 수행");
this.supplyTwoPhase();
}
}
6. 테스트 클래스
public class Notebook {
private final ThreePhasePower power;
public Notebook(ThreePhasePower power) {
this.power = power;
}
public void charge() {
power.supplyThreePhase();
}
public static void main(String[] args) {
ThreePhasePower direct = new ThreePhase();
direct.supplyThreePhase();
TwoPhase two = new TwoPhase();
ThreePhasePower adapted = new TwoToThreeAdapter(two);
new Notebook(adapted).charge();
adapted = new InheritanceAdapter();
new Notebook(adapted).charge();
}
}
팩토리 패턴
객체 생성 과정을 추상화하여 사용자에게 생성 로직을 숨기는 패턴입니다. 다양한 옵션을 제공하는 시스템에서 유용하게 활용됩니다.
1. 헤어 타입 인터페이스
public interface HairStyle {
void applyStyle();
}
2. 구체적 헤어 타입
public class LeftPart implements HairStyle {
public void applyStyle() {
System.out.println("왼쪽 편발 스타일 적용");
}
}
public class RightPart implements HairStyle {
public void applyStyle() {
System.out.println("오른쪽 편발 스타일 적용");
}
}
3. 팩토리 클래스
public class HairFactory {
public HairStyle createHair(String type) {
switch (type.toLowerCase()) {
case "left": return new LeftPart();
case "right": return new RightPart();
default: throw new IllegalArgumentException("Unsupported style");
}
}
public HairStyle createByClass(String className) {
try {
return (HairStyle) Class.forName(className).getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException("Class creation failed", e);
}
}
}
4. 테스트 클래스
public class HairTest {
public static void main(String[] args) {
HairStyle left = new LeftPart();
HairStyle right = new RightPart();
left.applyStyle();
right.applyStyle();
HairFactory factory = new HairFactory();
factory.createHair("left").applyStyle();
factory.createByClass("RightPart").applyStyle();
}
}
프록시 패턴
특정 객체에 대한 접근을 제어하는 중개자 역할을 수행하는 패턴입니다. 추가 기능을 동적으로 추가하거나 접근 제어가 필요한 경우 유용합니다.
1. 이동 가능한 인터페이스
public interface Movable {
void move();
}
2. 차량 클래스
public class Car implements Movable {
public void move() {
try {
System.out.println("차량 이동 중");
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3. 시간 기록 프록시
public class TimeTrackingProxy implements Movable {
private final Movable target;
public TimeTrackingProxy(Movable target) {
this.target = target;
}
public void move() {
long startTime = System.currentTimeMillis();
System.out.println("이동 시작");
target.move();
long endTime = System.currentTimeMillis();
System.out.println("이동 종료 - 소요 시간: " + (endTime - startTime) + "ms");
}
}
4. 로깅 프록시
public class LoggingProxy implements Movable {
private final Movable target;
public LoggingProxy(Movable target) {
this.target = target;
}
public void move() {
System.out.println("로그 시작");
target.move();
System.out.println("로그 종료");
}
}
5. JDK 동적 프록시
public class TimeHandler implements InvocationHandler {
private final Object target;
public TimeHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.currentTimeMillis();
System.out.println("이동 시작");
Object result = method.invoke(target, args);
long endTime = System.currentTimeMillis();
System.out.println("이동 종료 - 소요 시간: " + (endTime - startTime) + "ms");
return result;
}
}