设计模式-结构型模式

106 阅读4分钟

三、结构型模式(7)

结构型模式(Structural Patterns)
结构型模式关注类和对象的组合,用于简化结构,提供更灵活、更易于理解的系统设计。它们描述如何组合对象和类以获得更大的结构。

Decorator

装饰器(Decorator pattern)
Decorator模式允许在不修改对象现有代码的情况下动态地向对象添加职责。它通过提供一种将对象“包装”在类似接口的对象内的方法来实现这一点。
装饰模式是一种对象结构型模式。
皮肤

1.类图

类图
1.Component(组件):定义一个接口,为装饰者和被装饰的对象定义一个公共接口,这样可以在任何被装饰的对象上调用装饰者定义的任何方法。
2.ConcreteComponent(具体组件):实现了Component接口的类,即被装饰的原始对象。
3.Decorator(装饰器):持有一个Component对象的引用,并定义一个与Component接口一致的接口。可以在内部调用Component的方法,并可能增加额外的操作。
4.ConcreteDecorator(具体装饰器):实现Decorator接口,并在具体装饰者类中增加新的功能。

Adapter

适配器(Adapter pattern) Wrapper
adapter模式将类的接口转换为客户端期望的另一个接口,从而实现兼容性。
适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

1.Object Adapter

对象适配器(Object Adapter)
适配器类持有被适配对象的实例,并根据目标接口要求委托给这个实例的方法调用。
在对象适配器模式中,适配器与适配者之间是关联关系;在类适配器模式中,适配器与适配者之间是继承(或实现)关系。
对象适配器模式是适配器模式常用的一种。
类图
1.Target(目标接口):目标接口或抽象类定义了客户代码希望使用的接口形式。它是适配过程的目标规范,即我们希望适配后的对象能够符合的接口标准。
2.Adapter(适配器类):在对象适配器中,适配器类通常不直接继承Target,而是实现Target接口或继承Target抽象类,并在其内部持有Adaptee的一个实例。这样做是为了通过组合而非继承来达到复用Adaptee已有功能的目的。
3.Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下可能没有适配者类的源代码。

2.Class Adapter

类适配器(Class Adapter)
类适配器的核心思想是通过继承来调整一个类的接口,使其符合客户代码的期待。然而,在Java这样的语言中,由于多重继承的限制,这一模式更多地通过对象适配器(利用组合)来实现。在支持多重继承的语言中,类适配器则直接体现了这一模式的原始形态。
#include <iostream>// 目标接口
class TargetInterface {
public:
    virtual void request() = 0;
};
​
// 适配者类
class Adaptee {
public:
    void specificRequest() {
        std::cout << "Executing specific request in Adaptee." << std::endl;
    }
};
​
// 类适配器
class ClassAdapter : public Adaptee, public TargetInterface {
public:
    void request() override {
        specificRequest(); // 通过继承Adaptee并实现TargetInterface,完成适配
    }
};

3. Two-Way Adapter

双向适配器(Two-Way Adapter)
双向适配器是适配器模式的一个变体,它允许两个不兼容的接口不仅单向地工作在一起,还能够互相调用对方的方法。
// 目标接口
interface TargetInterface {
    void request();
}
​
// 目标实现类
class TargetImpl implements TargetInterface {
    @Override
    public void request() {
        System.out.println("Target received request.");
    }
​
    public void targetSpecificMethod() {
        System.out.println("Executing a method specific to Target.");
    }
}
​
// 适配者接口
interface AdapteeInterface {
    void specificRequest();
}
​
// 适配者实现类
class AdapteeImpl implements AdapteeInterface {
    @Override
    public void specificRequest() {
        System.out.println("Adaptee received specific request.");
    }
​
    public void adapteeSpecificMethod() {
        System.out.println("Executing a method specific to Adaptee.");
    }
}
​
// 双向适配器
class TwoWayAdapter implements TargetInterface, AdapteeInterface {
    private final TargetImpl target;
    private final AdapteeImpl adaptee;
​
    public TwoWayAdapter(TargetImpl target, AdapteeImpl adaptee) {
        this.target = target;
        this.adaptee = adaptee;
    }
​
    @Override
    public void request() {
        target.request();
    }
​
    @Override
    public void specificRequest() {
        adaptee.specificRequest();
    }
​
    // 允许Target访问Adaptee的方法
    public void callAdapteeMethod() {
        adaptee.adapteeSpecificMethod();
    }
​
    // 允许Adaptee访问Target的方法
    public void callTargetMethod() {
        target.targetSpecificMethod();
    }
}
​
public class Main {
    public static void main(String[] args) {
        TargetImpl target = new TargetImpl();
        AdapteeImpl adaptee = new AdapteeImpl();
        TwoWayAdapter adapter = new TwoWayAdapter(target, adaptee);
​
        // Target通过Adapter调用Adaptee方法
        adapter.callAdapteeMethod();
​
        // Adaptee通过Adapter调用Target方法
        adapter.callTargetMethod();
    }
}

4.接口适配器

接口适配器
接口适配器模式,也称为缺省适配器模式(Default Adapter Pattern),是一种特殊形式的对象适配器模式,它主要用于解决接口污染问题,即当一个类想要实现某个接口时,可能并不需要实现该接口中的所有方法。这种情况下,可以使用一个抽象类作为适配器,为接口中所有的方法提供默认(通常是空)实现,这样其他类继承这个抽象类时,只需要覆盖它们关心的方法即可。