구조 패턴(Structural Patterns)은 클래스와 객체를 조합하여 더 큰 구조를 만드는 데 중점을 둡니다. 이 패턴들은 클래스 간의 관계를 단순화하고 효율적으로 만들어 시스템의 유연성과 재사용성을 높이는 데 기여합니다. 아래에서는 주요 구조 패턴을 상세히 분석하겠습니다.
// 기존 인터페이스
interface Target {
void request();
}
// 기존 클래스
class Adaptee {
public void specificRequest() {
System.out.println("Specific request");
}
}
// 클래스 어댑터
class Adapter extends Adaptee implements Target {
public void request() {
specificRequest();
}
}
// 객체 어댑터
class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
adaptee.specificRequest();
}
}
// 구현부 인터페이스
interface Implementor {
void operationImpl();
}
// 구체적인 구현부
class ConcreteImplementorA implements Implementor {
public void operationImpl() {
System.out.println("ConcreteImplementorA operation");
}
}
// 추상층
abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
// 확장된 추상층
class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
public void operation() {
implementor.operationImpl();
}
}
// 구성 요소 인터페이스
interface Component {
void operation();
}
// 개별 객체
class Leaf implements Component {
public void operation() {
System.out.println("Leaf operation");
}
}
// 복합 객체
class Composite implements Component {
private List<Component> children = new ArrayList<>();
public void add(Component component) {
children.add(component);
}
public void remove(Component component) {
children.remove(component);
}
public void operation() {
for (Component child : children) {
child.operation();
}
}
}
// 구성 요소 인터페이스
interface Component {
void operation();
}
// 기본 구성 요소
class ConcreteComponent implements Component {
public void operation() {
System.out.println("ConcreteComponent operation");
}
}
// 데코레이터 클래스
abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
component.operation();
}
}
// 구체적인 데코레이터
class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
public void operation() {
super.operation();
addedBehavior();
}
private void addedBehavior() {
System.out.println("ConcreteDecoratorA added behavior");
}
}
// 서브시스템 클래스
class SubsystemA {
public void operationA() {
System.out.println("SubsystemA operation");
}
}
class SubsystemB {
public void operationB() {
System.out.println("SubsystemB operation");
}
}
// 퍼사드 클래스
class Facade {
private SubsystemA subsystemA;
private SubsystemB subsystemB;
public Facade() {
subsystemA = new SubsystemA();
subsystemB = new SubsystemB();
}
public void operation() {
subsystemA.operationA();
subsystemB.operationB();
}
}
// 플라이웨이트 인터페이스
interface Flyweight {
void operation(String extrinsicState);
}
// 구체적인 플라이웨이트
class ConcreteFlyweight implements Flyweight {
private String intrinsicState;
public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}
public void operation(String extrinsicState) {
System.out.println("IntrinsicState: " + intrinsicState + ", ExtrinsicState: " + extrinsicState);
}
}
// 플라이웨이트 팩토리
class FlyweightFactory {
private Map<String, Flyweight> flyweights = new HashMap<>();
public Flyweight getFlyweight(String key) {
if (!flyweights.containsKey(key)) {
flyweights.put(key, new ConcreteFlyweight(key));
}
return flyweights.get(key);
}
}
// 실제 객체 인터페이스
interface RealSubject {
void request();
}
// 실제 객체
class RealSubjectImpl implements RealSubject {
public void request() {
System.out.println("RealSubject request");
}
}
// 프록시 객체
class Proxy implements RealSubject {
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
public void request() {
System.out.println("Proxy request");
realSubject.request();
}
}
구조 패턴은 객체 지향 설계에서 중요한 역할을 하며, 다양한 상황에서 유연하고 효율적인 시스템을 설계하는 데 도움을 줍니다. 각 패턴을 적절히 사용하여 코드의 가독성, 유지 보수성, 확장성을 향상시키는 것이 중요합니다.