设计模式之结构型模式

前面一篇文章已经提到了设计模式之创建型模式,接下来我们说一说结构型模式

结构型模式

1. 适配器模式

适配器类充当了一个中间层,分为类适配器和对象适配器两种类型。类适配器使用继承来适配对象,而对象适配器使用组合来适配对象。

类适配器

// 目标接口
interface Target {
    void request();
}

// 被适配的类
class Adaptee {
    void specificRequest() {
        System.out.println("Adaptee specificRequest");
    }
}

// 类适配器类
class ClassAdapter extends Adaptee implements Target {
    @Override
    public void request() {
        specificRequest();
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        Target adapter = new ClassAdapter();
        adapter.request();
    }
}

对象适配器

// 目标接口
interface Target {
    void request();
}

// 被适配的类
class Adaptee {
    void specificRequest() {
        System.out.println("Adaptee specificRequest");
    }
}

// 对象适配器类
class ObjectAdapter implements Target {
    private Adaptee adaptee;

    public ObjectAdapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target adapter = new ObjectAdapter(adaptee);
        adapter.request();
    }
}

2. 桥接模式

在桥接模式中,存在两个独立的继承层次结构:抽象部分和实现部分。抽象部分定义了对象的接口,而实现部分则负责具体的实现。桥接模式通过将抽象部分与实现部分解耦,使得它们可以独立地变化,从而可以灵活地组合不同的抽象部分和实现部分。

// 实现部分接口
interface Implementor {
    void operationImpl();
}

// 具体实现类A
class ConcreteImplementorA implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("ConcreteImplementorA operation");
    }
}

// 具体实现类B
class ConcreteImplementorB implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("ConcreteImplementorB 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);
    }

    @Override
    public void operation() {
        System.out.println("RefinedAbstraction operation");
        implementor.operationImpl();
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        Implementor implementorA = new ConcreteImplementorA();
        Abstraction abstractionA = new RefinedAbstraction(implementorA);
        abstractionA.operation();

        Implementor implementorB = new ConcreteImplementorB();
        Abstraction abstractionB = new RefinedAbstraction(implementorB);
        abstractionB.operation();
    }
}

示例中,桥接模式将抽象部分(Abstraction)与实现部分(Implementor)分离,通过组合的方式将抽象部分和实现部分连接起来。这样就可以灵活地扩展和变化抽象部分和实现部分,而不会相互影响。

3. 组合模式

组合模式使得客户端可以统一处理单个对象和对象组合,从而使得组合对象与单个对象具有一致的行为。在组合模式中,有两种主要类型的对象:叶子节点(Leaf)和组合节点(Composite)。叶子节点表示树的最底层节点,它没有子节点,而组合节点可以包含子节点,形成树形结构。

// 组件接口
interface Component {
    void operation();
}

// 叶子节点类
class Leaf implements Component {
    private String name;

    public Leaf(String name) {
        this.name = name;
    }

    @Override
    public void operation() {
        System.out.println("Leaf " + name + " 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);
    }

    @Override
    public void operation() {
        for (Component component : children) {
            component.operation();
        }
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        Component leaf1 = new Leaf("A");
        Component leaf2 = new Leaf("B");
        Component leaf3 = new Leaf("C");

        Composite composite = new Composite();
        composite.add(leaf1);
        composite.add(leaf2);

        Composite nestedComposite = new Composite();
        nestedComposite.add(leaf3);
        composite.add(nestedComposite);

        composite.operation();
    }
}

示例中,Leaf 表示叶子节点,Composite 表示组合节点。组合节点可以包含叶子节点和其他组合节点,形成树形结构。客户端代码可以统一处理单个对象和对象组合,使用统一的接口对整个树形结构进行操作。组合模式能够更容易地处理嵌套结构,提高了系统的灵活性和可扩展性。

4. 装饰者模式

允许向对象动态地添加额外的功能,而无需修改其原始代码。装饰者模式通过创建一个装饰者类,该类包装原始对象,并在不改变其接口的情况下,扩展其功能。

在装饰者模式中,有四个关键角色:

  1. 抽象组件(Component):定义了一个抽象接口,可以是一个接口或者抽象类,用于定义装饰者和被装饰者的共同接口。
  2. 具体组件(Concrete Component):实现了抽象组件接口,是被装饰者的原始对象,可以动态地添加功能。
  3. 抽象装饰者(Decorator):实现了抽象组件接口,并持有一个指向抽象组件的引用,在其中可以动态地添加额外的功能。
  4. 具体装饰者(Concrete Decorator):继承自抽象装饰者,实现了具体的装饰逻辑,对原始对象进行装饰。
// 抽象组件
interface Coffee {
    String getDescription();
    double cost();
}

// 具体组件
class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }

    @Override
    public double cost() {
        return 1.0;
    }
}

// 抽象装饰者
abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;

    public CoffeeDecorator(Coffee decoratedCoffee) {
        this.decoratedCoffee = decoratedCoffee;
    }

    public String getDescription() {
        return decoratedCoffee.getDescription();
    }

    public double cost() {
        return decoratedCoffee.cost();
    }
}

// 具体装饰者
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee decoratedCoffee) {
        super(decoratedCoffee);
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription() + ", Milk";
    }

    @Override
    public double cost() {
        return decoratedCoffee.cost() + 0.5;
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        Coffee coffee = new SimpleCoffee();
        System.out.println(coffee.getDescription() + " costs $" + coffee.cost());

        Coffee milkCoffee = new MilkDecorator(coffee);
        System.out.println(milkCoffee.getDescription() + " costs $" + milkCoffee.cost());
    }
}

示例中,Coffee 是抽象组件,SimpleCoffee 是具体组件。CoffeeDecorator 是抽象装饰者,MilkDecorator 是具体装饰者。通过装饰者模式,我们可以动态地向原始对象添加额外的功能,而不需要修改原始对象的代码。

5. 外观模式

外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口,用来访问子系统中的一群接口。外观模式隐藏了子系统的复杂性,为客户端提供了一个简单的接口,使得客户端不需要了解子系统的具体实现细节。

外观模式通常包含以下角色:

  1. 外观(Facade):外观类是客户端访问子系统的入口,它封装了子系统的复杂性,提供了简单的接口供客户端调用。
  2. 子系统(SubSystem):子系统包含了一组类,实现了子系统的功能。客户端通过外观类与子系统进行交互。
// 子系统类A
class SystemA {
    public void operationA() {
        System.out.println("SystemA operation");
    }
}

// 子系统类B
class SystemB {
    public void operationB() {
        System.out.println("SystemB operation");
    }
}

// 子系统类C
class SystemC {
    public void operationC() {
        System.out.println("SystemC operation");
    }
}

// 外观类
class Facade {
    private SystemA systemA;
    private SystemB systemB;
    private SystemC systemC;

    public Facade() {
        systemA = new SystemA();
        systemB = new SystemB();
        systemC = new SystemC();
    }

    public void operation() {
        System.out.println("Facade operation");
        systemA.operationA();
        systemB.operationB();
.operationC        systemC();
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.operation();
    }
}

示例中,外观模式通过外观类 Facade 封装了子系统类 SystemA、SystemB、SystemC 的复杂操作,为客户端提供了一个简单的接口。客户端只需要通过外观类调用 operation 方法,而不需要了解子系统的具体实现细节。外观模式提供了一种简单的方式来访问复杂系统,降低了客户端与子系统之间的耦合度。

6. 享元模式

旨在减少系统中相似对象的数量,从而提高系统的性能和减少内存占用。享元模式通过共享相同的对象实例来减少对象的创建,适用于需要创建大量相似对象的场景。

在享元模式中,有两种关键的角色:

  1. 享元工厂(Flyweight Factory):负责创建和管理享元对象,通常实现为工厂模式。享元工厂可以维护一个享元池(Flyweight Pool),用于存储共享的享元对象。
  2. 享元对象(Flyweight):包含内部状态和外部状态,内部状态是可以共享的部分,而外部状态是不可以共享的部分。享元对象通常是不可变的。
import java.util.HashMap;

// 享元工厂
class FlyweightFactory {
    private HashMap<String, Flyweight> flyweights = new HashMap<>();

    public Flyweight getFlyweight(String key) {
        if (flyweights.containsKey(key)) {
            return flyweights.get(key);
        } else {
            Flyweight flyweight = new ConcreteFlyweight(key);
            flyweights.put(key, flyweight);
            return flyweight;
        }
    }
}

// 享元接口
interface Flyweight {
    void operation();
}

// 具体享元类
class ConcreteFlyweight implements Flyweight {
    private String key;

    public ConcreteFlyweight(String key) {
        this.key = key;
    }

    @Override
    public void operation() {
        System.out.println("ConcreteFlyweight " + key + " operation");
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();

        Flyweight flyweight1 = factory.getFlyweight("key1");
        flyweight1.operation();

        Flyweight flyweight2 = factory.getFlyweight("key2");
        flyweight2.operation();

        Flyweight flyweight3 = factory.getFlyweight("key1");
        flyweight3.operation();
    }
}

示例中,享元工厂负责创建和管理享元对象,通过享元工厂获取共享的享元对象,避免重复创建相同的对象。具体享元类包含了内部状态(key)和外部状态(operation),通过共享内部状态来减少对象的创建。享元模式可以在需要大量相似对象的场景中节省内存和提高性能。

7. 代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,目的是控制对对象的访问。代理模式可以为其他对象提供一个替代或占位符,以控制对这个对象的访问。
通过代理式模,可以实现对真实主题的访问控制、延迟加载、日志记录等功能。代理模式有助于提高系统的安全性、性能和可维护性。

在代理模式中,有三种主要角色:

  1. 抽象主题(Subject):定义了代理类和真实主题的共同接口,客户端通过这个接口访问真实主题。
  2. 真实主题(Real Subject):实现了抽象主题接口,是代理所代表的真实对象。
  3. 代理(Proxy):包含一个指向真实主题的引用,并且实现了抽象主题接口。代理可以在调用真实主题之前或之后执行额外的操作。
// 抽象主题接口
interface Subject {
    void request();
}

// 真实主题类
class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject: Processing request");
    }
}

// 代理类
class Proxy implements Subject {
    private RealSubject realSubject;

    public Proxy() {
        this.realSubject = new RealSubject();
    }

    @Override
    public void request() {
        System.out.println("Proxy: Logging request");
        realSubject.request();
        System.out.println("Proxy: Post-processing request");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Proxy proxy = new Proxy();
        proxy.request();
    }}

示例中,Subject 是抽象主题接口,定义了代理类和真实主题类的共同接口。RealSubject 是真实主题类,实现了抽象主题接口,是代理所代表的真实对象。Proxy 是代理类,包含一个指向 RealSubject 的引用,并实了抽现象主题接口。代理类在调用真实主题之前和之后添加了额外的操作。

  • 18
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值