设计模式之结构型模式

设计模式是软件开发中常见的解决方案,它们提供了一种在特定情况下解决常见问题的模板或框架。设计模式可以分为三大类:创建型模式、结构型模式和行为型模式。本文将重点介绍结构型模式(Structural Design Patterns),并详细探讨每一种模式的原理和应用。

什么是结构型模式?

结构型模式主要用于处理类或对象的组成结构,即如何将类或对象组合成更大的结构。这些模式通常关注于对象的组合、接口的设计以及类的组合关系。通过这些模式,我们可以更灵活地设计类结构,提高代码的可复用性和可维护性。

常见的结构型模式

1. 适配器模式(Adapter Pattern)

适配器模式用于将一个类的接口转换成客户端期望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

原理
  • 目标接口(Target Interface):客户端期望的接口。
  • 适配者类(Adaptee Class):需要适配的类,但它的接口与目标接口不兼容。
  • 适配器类(Adapter Class):实现目标接口,并持有适配者类的实例,通过委托适配者类的方法来实现目标接口的方法。
代码示例
// 目标接口
public interface Target {
    void request();
}

// 适配者类
public class Adaptee {
    public void specificRequest() {
        System.out.println("Adaptee specific request");
    }
}

// 适配器类
public class Adapter implements Target {
    private Adaptee adaptee;

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

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

// 客户端
public class Client {
    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target target = new Adapter(adaptee);
        target.request();
    }
}

2. 桥接模式(Bridge Pattern)

桥接模式将抽象部分与实现部分分离,使它们可以独立变化。桥接模式主要用于解决继承层次的膨胀问题,通过将继承关系转换为组合关系,提高系统的灵活性。

原理
  • 抽象部分(Abstraction):定义抽象接口,持有实现部分的引用。
  • 实现部分(Implementor):定义实现接口。
  • 具体实现部分(Concrete Implementor):实现实现接口。
  • 扩展抽象部分(Refined Abstraction):扩展抽象部分,通过组合关系调用具体实现部分的方法。
代码示例
// 实现接口
public interface Implementor {
    void operationImpl();
}

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

public class ConcreteImplementorB implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("ConcreteImplementorB operation");
    }
}

// 抽象部分
public abstract class Abstraction {
    protected Implementor implementor;

    public Abstraction(Implementor implementor) {
        this.implementor = implementor;
    }

    public abstract void operation();
}

// 扩展抽象部分
public class RefinedAbstraction extends Abstraction {
    public RefinedAbstraction(Implementor implementor) {
        super(implementor);
    }

    @Override
    public void operation() {
        implementor.operationImpl();
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Implementor implementorA = new ConcreteImplementorA();
        Implementor implementorB = new ConcreteImplementorB();

        Abstraction abstractionA = new RefinedAbstraction(implementorA);
        Abstraction abstractionB = new RefinedAbstraction(implementorB);

        abstractionA.operation();
        abstractionB.operation();
    }
}

3. 组合模式(Composite Pattern)

组合模式允许你将对象组合成树形结构来表示部分-整体的层次结构。组合模式使得客户端可以一致地对待单个对象和对象组合。

原理
  • 组件(Component):定义树中每个对象的共有接口,包含单个对象和组合对象的方法。
  • 叶子(Leaf):表示树中的终端节点,没有子节点。
  • 组合(Composite):表示树中的非终端节点,包含多个子节点,并实现组件接口。
代码示例
// 组件接口
public interface Component {
    void operation();
}

// 叶子类
public class Leaf implements Component {
    @Override
    public void operation() {
        System.out.println("Leaf operation");
    }
}

// 组合类
public 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() {
        System.out.println("Composite operation");
        for (Component child : children) {
            child.operation();
        }
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Composite root = new Composite();
        Composite branch = new Composite();

        Leaf leaf1 = new Leaf();
        Leaf leaf2 = new Leaf();

        branch.add(leaf1);
        branch.add(leaf2);

        root.add(branch);
        root.add(new Leaf());

        root.operation();
    }
}

4. 装饰器模式(Decorator Pattern)

装饰器模式是一种动态地给对象添加新的功能的方法,通过创建一个包装对象来包裹真实的对象。装饰器模式可以在运行时选择不同的装饰器,以增加或改变对象的行为。

原理
  • 组件接口(Component Interface):定义被装饰对象的接口。
  • 具体组件(Concrete Component):实现组件接口的对象。
  • 装饰器类(Decorator Class):实现组件接口,并持有具体组件的引用,通过组合关系动态地添加功能。
  • 具体装饰器(Concrete Decorator):扩展装饰器类,添加新的功能。
代码示例
// 组件接口
public interface Component {
    void operation();
}

// 具体组件
public class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("ConcreteComponent operation");
    }
}

// 装饰器类
public abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation();
    }
}

// 具体装饰器
public class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();
        addedBehavior();
    }

    private void addedBehavior() {
        System.out.println("Added behavior A");
    }
}

public class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        super.operation();
        addedBehavior();
    }

    private void addedBehavior() {
        System.out.println("Added behavior B");
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        Component decoratedA = new ConcreteDecoratorA(component);
        Component decoratedB = new ConcreteDecoratorB(decoratedA);

        decoratedB.operation();
    }
}

5. 代理模式(Proxy Pattern)

代理模式为其他对象提供一个代理以控制对这个对象的访问。代理模式可以在不改变原对象的前提下,增加额外的功能或控制。

原理
  • 主题接口(Subject Interface):定义真实对象和代理对象的共同接口。
  • 真实主题(Real Subject):实现主题接口,提供实际的业务逻辑。
  • 代理对象(Proxy Object):实现主题接口,持有真实主题的引用,并在调用真实主题的方法时增加额外的操作。
代码示例
// 主题接口
public interface Subject {
    void request();
}

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

// 代理对象
public class Proxy implements Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        before();
        realSubject.request();
        after();
    }

    private void before() {
        System.out.println("Proxy: Before request");
    }

    private void after() {
        System.out.println("Proxy: After request");
    }
}

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

6. 享元模式(Flyweight Pattern)

享元模式用于减少创建大量相似对象的内存开销,通过共享这些对象来节省内存。享元模式适用于对象的主要状态可以外部化,而内部状态可以共享的场景。

原理
  • 享元接口(Flyweight Interface):定义享元对象的公共接口。
  • 具体享元(Concrete Flyweight):实现享元接口,存储内部状态。
  • 外部状态:由客户端存储,通过参数传递给享元对象。
  • 享元工厂(Flyweight Factory):管理享元对象的创建和共享。
代码示例
// 享元接口
public interface Flyweight {
    void operation(String state);
}

// 具体享元
public class ConcreteFlyweight implements Flyweight {
    private String intrinsicState;

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

    @Override
    public void operation(String state) {
        System.out.println("ConcreteFlyweight: " + intrinsicState + " + " + state);
    }
}

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

    public Flyweight getFlyweight(String intrinsicState) {
        if (!flyweights.containsKey(intrinsicState)) {
            flyweights.put(intrinsicState, new ConcreteFlyweight(intrinsicState));
        }
        return flyweights.get(intrinsicState);
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        FlyweightFactory factory = new FlyweightFactory();
        Flyweight flyweight1 = factory.getFlyweight("State1");
        Flyweight flyweight2 = factory.getFlyweight("State1");
        Flyweight flyweight3 = factory.getFlyweight("State2");

        flyweight1.operation("ExternalState1");
        flyweight2.operation("ExternalState2");
        flyweight3.operation("ExternalState3");
    }
}

7. 外观模式(Facade Pattern)

外观模式提供了一个统一的接口,用于访问子系统中的一群接口。外观模式定义了一个高层接口,使子系统的使用更加简单。

原理
  • 子系统(Subsystems):包含多个复杂的类和接口。
  • 外观(Facade):提供一个简单的接口,封装子系统的复杂性。
  • 客户端(Client):通过外观接口访问子系统。
代码示例
// 子系统类1
public class Subsystem1 {
    public void operation1() {
        System.out.println("Subsystem1 operation1");
    }
}

// 子系统类2
public class Subsystem2 {
    public void operation2() {
        System.out.println("Subsystem2 operation2");
    }
}

// 外观类
public class Facade {
    private Subsystem1 subsystem1 = new Subsystem1();
    private Subsystem2 subsystem2 = new Subsystem2();

    public void operation() {
        subsystem1.operation1();
        subsystem2.operation2();
    }
}

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

8. 门面模式(Facade Pattern)

门面模式(Facade Pattern)和外观模式实际上是同一种模式,提供了一个简单的接口,用于访问子系统中的一群接口。门面模式使子系统的使用更加简单和高效。

原理
  • 子系统(Subsystems):包含多个复杂的类和接口。
  • 门面(Facade):提供一个简单的接口,封装子系统的复杂性。
  • 客户端(Client):通过门面接口访问子系统。
代码示例

(与外观模式相同,参见上述代码示例)

总结

结构型模式主要用于处理类或对象的组成结构,通过组合、委托、封装等方式,提高代码的可复用性和可维护性。常见的结构型模式包括适配器模式、桥接模式、组合模式、装饰器模式、代理模式、享元模式和外观模式。每种模式都有其独特的应用场景和优点,理解并掌握这些模式可以帮助我们在实际开发中更好地设计和优化代码结构。

希望你喜欢这篇文章!请点关注和收藏吧。你的关注和收藏会是我努力更新的动力,祝关注和收藏的帅哥美女们今年都能暴富。如果有更多问题,欢迎随时提问

相关推荐
啦啦右一2 分钟前
SpringMVC |(一)SpringMVC概述
java·后端·spring
坚定信念,勇往无前2 分钟前
springboot aop @Pointcut 的 12 种用法
java·spring boot·spring
皮克斯的进化之路3 分钟前
什么是Spring IOC和Spring AOP?
java·后端·spring
老牛源码15 分钟前
Z2400027基于Java+SpringBoot+Mysql+thymeleaf引擎的图书馆管理系统的设计与实现 代码 论文
java·spring boot·mysql
多多*18 分钟前
后端 Java发送邮件 JavaMail 模版 20241128测试可用
java·开发语言·数据库
刘大浪21 分钟前
IDEA 2024 Maven 设置为全局本地仓库,避免新建项目重新配置maven
java·maven·intellij-idea
老马啸西风22 分钟前
jvm-44-jvm 内存性能分析工具 Eclipse Memory Analyzer Tool (MAT) / 内存分析器 (MAT)
java
鸣弦artha24 分钟前
蓝桥杯——递归
java·数据结构·算法·蓝桥杯·eclipse
冷瞳31 分钟前
认识RabbitMq和RabbitMq的使用
java·rabbitmq·java-rabbitmq