设计模式

80 阅读7分钟

类图

类图定义

描述类的特性以及类与类之间的关系。

类图的组成

  1. 类名
  2. 属性列表
  3. 方法列表
  4. 类之间的关系
    1. 聚合
      • 部分与整体的关系,其聚合中的部分实体可独立存在
      • 标识方法空菱形+实线箭头
    2. 组合
      • 由各个部分组合而成,部分实体独立存在时无实际意义。
      • 标识方法实心菱形+实现箭头
    3. 继承
      • 继承用于描述子父类之间的关系。
      • 标识方法 实线+空心箭头
    4. 实现
      • 用于接口与接口件的实现类
      • 标识方法 虚线+ 空心箭头
    5. 依赖
      • 两个独立对象,一个对象负责构建另一个对象的实例,或者依赖另一个对象的服务时。两个对象之间的主体为依赖关系。
      • PS:在java中一般指局部变量,方法参数,静态方法的调用等。
      • 使用虚线箭头表述 ---->
    6. 关联
      • 类与类之间的连接,一个类了解另一个类的属性与方法。A类关联B类 A类将B类的对象作为成员变量
      • 标识方法 实线箭头

类图应用场景

描述类之间的静态关系

应用阶段

详细设计

设计模式

原型模式

分类

浅拷贝
其值对象为value 复制,
引用对象为指向对应的引用
深拷贝
值对象为value 复制
引用对象新创建的引用,并进行值复制

适用场景

对象创建逻辑繁琐,且耗时的场景。复杂的数据库查询,网络请求,或大量计算才能构建的对象

原型图

classDiagram
Prototype <|-- ConcretePrototypeShallow
Prototype <|-- ConcretePrototypeDepth
Prototype : -String id
Prototype : + abstract Prototype clone()
class ConcretePrototypeShallow{
+clone()
}
class ConcretePrototypeDepth{
+clone()
}

模版方法模式

适用场景

  • 算法结构固定,步骤可变
  • 避免重复代码
  • 控制子类的扩展

原型图

classDiagram
abstract Template <|-- ConcreteTemplate
abstract Template : + templateMethod()
abstract Template : +  abstract operation01()
abstract Template : +  abstract operation02()
class ConcreteTemplate{
   +operation01()
   +operation02()
}

外观模式

适用场景

结构化的设计模式,为各个复杂的子系统定义高度抽象简化接口。使得用户端可以更容易的使用子系统,外观模式隐匿了子系统的复杂性

  • 简化子系统的使用
  • 减少客户端与子系统件的依赖
  • 分层架构

原型图

classDiagram
Facade --> SubSystem01
Facade --> SubSystem02
Facade --> SubSystem03

class Facade{
- SubSystem01 subSystem01
- SubSystem01 subSystem02
- SubSystem03 subSystem03
}
class SubSystem01{
 + operation01()
}
class SubSystem02{
 + operation02()
}
class SubSystem03{
 + operation03()
}

构造器模式

使用场景

创建型设计模式,其允许一步步的构建复杂对象。建造者模式将对象的构建以及对象的表示进行分离。使得同样的构建过程可以创建不同的表示

  • 复杂对象的构建
  • 不同的表示对象
  • 隔离复杂对象创建以及表示

组成

  • Product
  • Builder 抽象接口,定义其构建对象的方法
  • ConcreteBuilder 具体的建造者,实现Builder接口
  • Director 调用构造者的方法,按照构建顺序进行产品构建

原型图

classDiagram
Builder <|--ConcreteBuilder
Director o--Builder
Product <.. ConcreteBuilder 
class Builder{
 + buildPart();
}
class Director{
 + construct();
}
class ConcreteBuilder{
 + buildPart();
 + getBuildResult();
}

命令模式

场景

  • 队列请求:需要将请求排队,按顺序执行。
  • 日志记录:需要记录请求日志,以便在系统崩溃后恢复。
  • 撤销操作:需要支持撤销操作,可以保存命令对象的历史记录。
  • 宏命令:可以将一组命令组合成一个宏命令,一次性执行多个操作。

组成元素

  • 命令接口 声明一个操作的接口

  • 具体的命令

    • 具体的命令对象,用于实现命令接口,负责具体的操作
    • 命令的接受者作为聚合对象之一,将具体的命令实施委托给命令的接收者
  • 命令的接收者

    • 负责具体的命令的实施
  • 调用者

    • 负责调用命令对象,将对象存储至队列中,依据顺序执行
  • 客户端

    • 创建具体的命令对象,并设置其接收者
    • 将命令传递给调用者

类图

classDiagram
Command <|.. ConcreteCommand
Command: +excute()
ConcreteCommand <..Receiver
Invoker o--Command
class ConcreteCommand{
-Receiver commandReceiver
+execute()
}
class Receiver{
 +action()
}
class Invoker{
-Command concreteCommand
+ triggerCommandExecute()
}

class Client{
  + main()

}

示例

/** 1.客户端创建接收者
    2. 实例化具体的命令,并将接收者作为参数进行绑定
    3. 构建命令的调用者
    4. 设定具体的额命令作为调用者的参数
    5. 调用者驱动命令方法,触发命令执行

**/
public class Client {
    public static void main(String[] args) {
        Light light = new Light(); // 创建接收者
        Command lightOn = new LightOnCommand(light); // 创建具体命令

        RemoteControl remote = new RemoteControl(); // 创建调用者
        remote.setCommand(lightOn); // 设置命令
        remote.pressButton(); // 执行命令
    }
}

public class RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        command.execute();
    }
}


public class Light {
    public void on() {
        System.out.println("Light is on");
    }

    public void off() {
        System.out.println("Light is off");
    }
}

public class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.on();
    }
}

public interface Command { void execute(); }

责任链模式

场景

责任链模式按照需求顺序处理请求,并且每个处理者可以有条件的处理请求或者将其传递给下一个处理者。

组成

  • 处理者 声明一个处理接口,并且包含一个指向下一个处理者的引用。
  • 具体的处理者程序 实现具体的处理接口,依据条件判定是否要进行处理,并在必要时传递给下一个处理者
  • 客户端 构建处理者链条并将请求发送至处理链条中的第一个处理者

类图

classDiagram
Handler <|.. ConcreteHandler
Handler : + void handleRequest(Request request)
Handler: - ConcreteHandler concreteHandler
Client..Handler
Client..Request
class Request{
  -String requestConent;
  -String requstCondition;

}
class ConcreteHandler{
- ConcreteHandler concreteHandler
+ void handleRequest(request)
}
class Client{
-Request request
-Handler concreteHandler
}

示例

public class Request {
    private String type;

    public Request(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }
}

public interface Handler {
    void setNext(Handler next);
    void handleRequest(Request request);
}

public class Handler1 implements Handler {
    private Handler next;

    @Override
    public void setNext(Handler next) {
        this.next = next;
    }

    @Override
    public void handleRequest(Request request) {
        if (request.getType().equals("Type1")) {
            System.out.println("Handler1 handled the request.");
        } else if (next != null) {
            next.handleRequest(request);
        }
    }
}

public class Handler2 implements Handler {
    private Handler next;

    @Override
    public void setNext(Handler next) {
        this.next = next;
    }

    @Override
    public void handleRequest(Request request) {
        if (request.getType().equals("Type2")) {
            System.out.println("Handler2 handled the request.");
        } else if (next != null) {
            next.handleRequest(request);
        }
    }
}

public class Handler3 implements Handler {
    private Handler next;

    @Override
    public void setNext(Handler next) {
        this.next = next;
    }

    @Override
    public void handleRequest(Request request) {
        if (request.getType().equals("Type3")) {
            System.out.println("Handler3 handled the request.");
        } else if (next != null) {
            next.handleRequest(request);
        }
    }
}

    public static void main(String[] args) {
        Handler handler1 = new Handler1();
        Handler handler2 = new Handler2();
        Handler handler3 = new Handler3();

        handler1.setNext(handler2);
        handler2.setNext(handler3);

        Request request1 = new Request("Type1");
        Request request2 = new Request("Type2");
        Request request3 = new Request("Type3");
        Request request4 = new Request("Type4");

        handler1.handleRequest(request1); // Handler1 handles it
        handler1.handleRequest(request2); // Handler2 handles it
        handler1.handleRequest(request3); // Handler3 handles it
        handler1.handleRequest(request4); // No handler, request is ignored
    }
}


中介者模式|调停者模式

场景

  • 多个对象之间存在复杂的交互逻辑,且交互逻辑可进行集中管理
  • 减少对象件直接逻辑交互
  • GUI 聊天系统 多玩家

组成

  • 中介者Mediator
    • 声明接口用于与同事间的通信
    • 一个或多个对象的引用
  • 具体的中介者Concrete Mediator
    • 实现中介者接口,协调各同事之间的交互
    • 负责管理同事负责其之间的通信
  • 同事 Colleague
    • 定义一个接口,同事对象可以通过其与其他中介者通信
    • 包含一个中介者的引用
  • 具体同事
    • 实现同事接口,与中介者通信,并可能与其他同事通信

类图

classDiagram
Mediator <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}

访问中文模式

场景

访问者模式描述的是行为模式,实现数据元素与数据操作的依据访问者的不同展示不同的行为。

组成

  1. 访问者接口
    1. 具体的访问者
  2. 被访问的元素 2. 具体的被访问元素
  3. 对象结构
  4. 客户端

类图

classDiagram
Visitor <|-- ConcreteVisitorA
Visitor <|-- ConcreteVisitorB
Visitor: +abstract visit(Element concreteElement)
Element <|-- ConcreteElementA
Element  <|-- ConcreteElementB
Element: + abstract accept(Vistor concreteVisitor)
Client--> ObjectStructor
ObjectStructor-->Visitor
Client--> Element
class ConcreteVisitorA{
   +visitor(Element concreteElement)
}

class ConcreteVisitorB{
   +visitor(Element concreteElement)
}

class ConcreteElementA {
   +accept(Visitor concreteVistor)

}
class ConcreteElementB{
   +accept(Visitor concreteVistor)

}

代码示例

interface Visitor {
    void visit(Book book);
    void visit(Magazine magazine);
}
class PrintVisitor implements Visitor {
    @Override
    public void visit(Book book) {
        System.out.println("书名: " + book.getTitle() + ", 作者: " + book.getAuthor());
    }

    @Override
    public void visit(Magazine magazine) {
        System.out.println("杂志名: " + magazine.getName() + ", 期号: " + magazine.getIssueNumber());
    }
}

class PriceVisitor implements Visitor {
    @Override
    public void visit(Book book) {
        System.out.println("书名: " + book.getTitle() + ", 价格: " + book.getPrice());
    }

    @Override
    public void visit(Magazine magazine) {
        System.out.println("杂志名: " + magazine.getName() + ", 价格: " + magazine.getPrice());
    }
}

interface Element {
    void accept(Visitor visitor);
}
class Book implements Element {
    private String title;
    private String author;
    private double price;

    public Book(String title, String author, double price) {
        this.title = title;
        this.author = author;
        this.price = price;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public double getPrice() {
        return price;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
class Book implements Element {
    private String title;
    private String author;
    private double price;

    public Book(String title, String author, double price) {
        this.title = title;
        this.author = author;
        this.price = price;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public double getPrice() {
        return price;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
import java.util.ArrayList;
import java.util.List;

class ObjectStructure {
    private List<Element> elements = new ArrayList<>();

    public void addElement(Element element) {
        elements.add(element);
    }

    public void removeElement(Element element) {
        elements.remove(element);
    }

    public void accept(Visitor visitor) {
        for (Element element : elements) {
            element.accept(visitor);
        }
    }
}
import java.util.ArrayList;
import java.util.List;

class ObjectStructure {
    private List<Element> elements = new ArrayList<>();

    public void addElement(Element element) {
        elements.add(element);
    }

    public void removeElement(Element element) {
        elements.remove(element);
    }

    public void accept(Visitor visitor) {
        for (Element element : elements) {
            element.accept(visitor);
        }
    }
}
    public static void main(String[] args) {
        ObjectStructure objectStructure = new ObjectStructure();

        // 添加元素
        objectStructure.addElement(new Book("Java编程思想", "Bruce Eckel", 100.0));
        objectStructure.addElement(new Magazine("科学美国人", 123, 30.0));

        // 创建访问者
        Visitor printVisitor = new PrintVisitor();
        Visitor priceVisitor = new PriceVisitor();

        // 接受访问者
        System.out.println("打印信息:");
        objectStructure.accept(printVisitor);

        System.out.println("计算价格:");
        objectStructure.accept(priceVisitor);
    }
}