GoF设计模式——结构型设计模式分析与应用

文章目录

    • [UML图的结构主要表现为:继承(抽象)、关联 、组合或聚合 的三种关系。](#UML图的结构主要表现为:继承(抽象)、关联 、组合或聚合 的三种关系。)
      • [1. 继承(抽象,泛化关系)](#1. 继承(抽象,泛化关系))
      • [2. 关联](#2. 关联)
      • [3. 组合/聚合](#3. 组合/聚合)
      • 各种可能的配合:
        • [1. 关联后抽象](#1. 关联后抽象)
        • [2. 关联的集合](#2. 关联的集合)
        • [3. 组合接口](#3. 组合接口)
        • [4. 递归聚合接口](#4. 递归聚合接口)
      • Adapter
      • Bridge
      • Composite
      • Decorator
      • Facade
      • Flyweight
      • Proxy

GoF(Gang of Four)设计模式的三大类:

  • 创建型设计模式(Creational Patterns)
  • 结构型设计模式(Structural Patterns)
  • 行为设计模式(Behavioral Patterns)

Object Scope 可用于运行时

Class Scope 只能用于编译时


UML图的结构主要表现为:继承(抽象)、关联 、组合或聚合 的三种关系。

车是交通工具,车是我的,车里有发动机

1. 继承(抽象,泛化关系)

class Vehicle {
    String name;
    void move() {}
}

class Car extends Vehicle {
    void drive() {}
}

2. 关联

class Person {
    Car car; // 关联关系
}

class Car {
    String model;
}

3. 组合/聚合

class Car {
    Engine engine; // 组合关系
    GPS gps;       // 聚合关系
}

class Engine {}
class GPS {}

各种可能的配合:

圈住部分即为原因。

1. 关联后抽象
2. 关联的集合
3. 组合接口
4. 递归聚合接口

这里递归怎么理解?

其实是虽然我的装饰器实现了这个接口,但是我的装饰器类内部成员可能还有有这个接口类



Adapter

适配器模式能够将不兼容的接口转换成兼容的接口,从而使得原本无法直接交互的类能够合作。

可以在不修改现有代码的情况下,重用第三方的功能或代码。

可以在不同的系统间进行灵活的接口转换,尤其适用于系统集成和迁移。

Adapter(适配器)设计模式

继承+关联 ("关联后抽象")

" 加一层,新接口。"

("R"标记:可运行时改变;实心箭头指实现,空心指泛化)

设计逻辑的层次:

  • 先从具体类(ConcreteAdapter)的实现入手,明确其与其他类的关联(如 Adaptee)。

  • 然后在其上进一步抽象出一个统一的接口(Adapter),以适应多种实现需求。

    // 老版本的播放器接口
    class OldMediaPlayer {
    void playAudio() {
    System.out.println("Playing audio...");
    }
    }

    // 新播放器接口
    interface ModernPlayer {
    void play();
    }

    // 适配器类
    class PlayerAdapter implements ModernPlayer {
    private OldMediaPlayer oldMediaPlayer;

      public PlayerAdapter(OldMediaPlayer oldMediaPlayer) {
          this.oldMediaPlayer = oldMediaPlayer;
      }
    
      @Override
      public void play() {
          oldMediaPlayer.playAudio(); // 使用旧方法适配新接口
      }
    

    }

    // 客户端代码
    public class AdapterExample {
    public static void main(String[] args) {
    OldMediaPlayer oldPlayer = new OldMediaPlayer();
    ModernPlayer modernPlayer = new PlayerAdapter(oldPlayer);

          modernPlayer.play(); // 使用新接口播放
      }
    

    }


Bridge

解耦抽象和实现:桥接模式将抽象部分与实现部分分离,可以独立地扩展两者。

新增抽象层或者实现层时,不会影响到对方,增强了系统的可扩展性。

避免重复代码,增加代码复用性。

Bridge(桥)设计模式

组合接口

" 比如形状类里加个颜色类。 而该形状可以在各种地方使用"

// 实现接口
interface Color {
    String fill();
}

class Red implements Color {
    public String fill() {
        return "Color is Red";
    }
}

class Blue implements Color {
    public String fill() {
        return "Color is Blue";
    }
}

// 抽象类
abstract class Shape {
    protected Color color;

    public Shape(Color color) {
        this.color = color;
    }

    abstract void draw();
}

class Circle extends Shape {
    public Circle(Color color) {
        super(color);
    }

    public void draw() {
        System.out.println("Drawing Circle. " + color.fill());
    }
}

// 客户端代码
public class BridgeExample {
    public static void main(String[] args) {
        Shape redCircle = new Circle(new Red());
        Shape blueCircle = new Circle(new Blue());

        redCircle.draw();
        blueCircle.draw();
    }
}

Composite

树形结构:组合模式允许你以树形结构来组合对象,简化了对象的管理和处理。

统一操作:可以统一对单个对象和组合对象的处理,客户端不需要知道是单一对象还是组合对象。

递归结构:支持递归组合,使得层次结构更易于表示和管理,特别适用于有层次结构的对象模型。

Composite(组合)设计模式

递归聚合接口

"可以都放进一个容器,装满书的书包"

书包里可能还有一个书包,所以书包的"聚合"里,还有component抽象类------递归。

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

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

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

    public void operation() {
        System.out.println("Leaf: " + name);
    }
}

// 容器节点
class Composite implements Component {
    private List<Component> children = new ArrayList<>();

    public void add(Component component) {
        children.add(component);
    }

    public void operation() {
        for (Component child : children) {
            child.operation();
        }
    }
}

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

        Leaf leaf1 = new Leaf("Leaf 1");
        Leaf leaf2 = new Leaf("Leaf 2");

        Composite subTree = new Composite();
        subTree.add(new Leaf("SubTree Leaf 1"));

        root.add(leaf1);
        root.add(leaf2);
        root.add(subTree);

        root.operation(); // 遍历树形结构
    }
}

Decorator

动态扩展功能:装饰器模式可以在运行时动态地给对象添加新的功能,而不改变原有类的代码。

增加灵活性:通过装饰器,可以为对象添加多种功能,客户端可以根据需求进行组合,增加了系统的灵活性。

符合开放/关闭原则:装饰器通过扩展功能,而不是修改类本身,符合开放/关闭原则。

Decorator(装饰器)设计模式

递归聚合接口

"对不同物品可以进行不同装饰"

"两组抽象和实现。

装饰器里有【具体部件】和新的方法"

// 抽象组件(饮料)
interface Beverage {
    String getDescription();
    double cost();
}

// 具体组件
class Coffee implements Beverage {
    public String getDescription() {
        return "Coffee";
    }

    public double cost() {
        return 5.0;
    }
}

// 装饰器
abstract class AddOnDecorator implements Beverage {
    protected Beverage beverage;

    public AddOnDecorator(Beverage beverage) {
        this.beverage = beverage;
    }
}

class Milk extends AddOnDecorator {
    public Milk(Beverage beverage) {
        super(beverage);
    }

    public String getDescription() {
        return beverage.getDescription() + ", Milk";
    }

    public double cost() {
        return beverage.cost() + 1.0;
    }
}

class Sugar extends AddOnDecorator {
    public Sugar(Beverage beverage) {
        super(beverage);
    }

    public String getDescription() {
        return beverage.getDescription() + ", Sugar";
    }

    public double cost() {
        return beverage.cost() + 0.5;
    }
}

// 客户端代码
public class DecoratorExample {
    public static void main(String[] args) {
        Beverage beverage = new Coffee();
        beverage = new Milk(beverage);
        beverage = new Sugar(beverage);

        System.out.println(beverage.getDescription() + " costs " + beverage.cost());
    }
}

Facade

简化接口:外观模式为复杂子系统提供了一个统一的、高层的接口,简化了客户端的调用方式。

降低耦合:客户端不需要了解各个子系统的实现细节,只需要与外观类交互,从而降低了系统的耦合度。

便于扩展:如果需要修改子系统的实现,可以在外观类中进行修改,而不影响客户端代码。

Façade(门面)设计模式

关联的集合

"将各个组件集成在一起"

class CPU {
    public void start() {
        System.out.println("CPU started.");
    }
}

class Memory {
    public void load() {
        System.out.println("Memory loaded.");
    }
}

class HardDrive {
    public void readData() {
        System.out.println("HardDrive read data.");
    }
}

// 门面类
class ComputerFacade {
    private CPU cpu;
    private Memory memory;
    private HardDrive hardDrive;

    public ComputerFacade() {
        this.cpu = new CPU();
        this.memory = new Memory();
        this.hardDrive = new HardDrive();
    }

    public void start() {
        cpu.start();
        memory.load();
        hardDrive.readData();
    }
}

// 客户端代码
public class FacadeExample {
    public static void main(String[] args) {
        ComputerFacade computer = new ComputerFacade();
        computer.start(); // 一键启动
    }
}

Flyweight

内存优化:享元模式通过共享相同的对象实例,减少了内存的消耗,尤其适用于大量相似对象的场景。

提高性能:由于共享对象的使用,可以减少对象的创建和销毁,提高了系统的性能。

Flyweight(享元)设计模式

关联的集合

"共享的懒汉模式"

// 抽象享元
interface Shape {
    void draw();
}

// 具体享元
class Circle implements Shape {
    private String color;

    public Circle(String color) {
        this.color = color;
    }

    public void draw() {
        System.out.println("Drawing " + color + " Circle");
    }
}

// 享元工厂
class ShapeFactory {
    private static Map<String, Shape> shapeMap = new HashMap<>();

    public static Shape getCircle(String color) {
        if (!shapeMap.containsKey(color)) {
            shapeMap.put(color, new Circle(color));
            System.out.println("Created new " + color + " Circle");
        }
        return shapeMap.get(color);
    }
}

// 客户端代码
public class FlyweightExample {
    public static void main(String[] args) {
        Shape redCircle = ShapeFactory.getCircle("Red");
        Shape blueCircle = ShapeFactory.getCircle("Blue");
        Shape anotherRedCircle = ShapeFactory.getCircle("Red");

        redCircle.draw();
        blueCircle.draw();
        anotherRedCircle.draw(); // 复用红色圆
    }
}

Proxy

控制访问:代理模式可以控制对真实对象的访问,例如延迟加载、权限控制、缓存等。

增强功能:代理类可以为目标对象增加额外的功能,比如日志记录、安全控制等,而不需要修改目标对象的代码。

降低耦合:代理类和目标类相互独立,客户端通过代理类访问目标对象,减少了对目标类的直接依赖。

Proxy(代理)设计模式

关联后抽象

"懒汉模式"

// 抽象接口
interface Image {
    void display();
}

// 真实类
class RealImage implements Image {
    private String fileName;

    public RealImage(String fileName) {
        this.fileName = fileName;
        loadFromDisk();
    }

    private void loadFromDisk() {
        System.out.println("Loading " + fileName);
    }

    public void display() {
        System.out.println("Displaying " + fileName);
    }
}

// 代理类
class ProxyImage implements Image {
    private RealImage realImage;
    private String fileName;

    public ProxyImage(String fileName) {
        this.fileName = fileName;
    }

    public void display() {
        if (realImage == null) {
            realImage = new RealImage(fileName); // 延迟加载
        }
        realImage.display();
    }
}

// 客户端代码
public class ProxyExample {
    public static void main(String[] args) {
        Image image = new ProxyImage("test.jpg");
        image.display(); // 加载并显示
        image.display(); // 再次显示,无需加载
    }
}

相关推荐
唐僧洗头爱飘柔952742 分钟前
(Java并发编程——JUC)常见的设计模式概念分析与多把锁使用场景!!理解线程状态转换条件!带你深入JUC!!文章全程笔记干货!!
java·设计模式·并发编程·juc·reentrantlock·顺序控制·生产者与消费者
澄澈i2 小时前
设计模式学习[9]---模板方法模式
c++·学习·设计模式·模板方法模式
zzzhpzhpzzz2 小时前
设计模式——解释器模式
算法·设计模式·解释器模式
repinkply4 小时前
装饰模式(Decorator)模式:装饰模式/包装模式,结构模式
设计模式·c++设计模式·装饰器模式·装饰模式·包装模式
霁月风5 小时前
设计模式——装饰器模式
c++·设计模式·装饰器模式
夏旭泽5 小时前
设计模式-原型模式
设计模式·原型模式
zzzhpzhpzzz6 小时前
设计模式——观察者模式
算法·观察者模式·设计模式
小白不太白9507 小时前
设计模式之 迭代器模式
java·设计模式·迭代器模式
闲人一枚(学习中)7 小时前
设计模式-创建型-单例模式
java·单例模式·设计模式