首页 > 其他分享 >设计模式的原则(一)

设计模式的原则(一)

时间:2023-06-17 21:06:18浏览次数:29  
标签:info log 原则 void class new 设计模式 public


相信自己,无论自己到了什么局面,请一定要继续相信自己。

新的世界开始了,接下来,老蝴蝶带领大家学习一下设计模式。

我们先了解一下 设计原则

一.设计模式

一.一 设计原则

设计模式常用的七大原则:

  1. 单一职责原则
  2. 接口隔离原则
  3. 依赖倒转(倒置)原则
  4. 里氏替换原则
  5. 开闭原则
  6. 迪米特法则
  7. 合成复用原则

一.二 设计模式的目的

编写软件过程中,程序员面临着来自 耦合性,内聚性以及可维护性,可扩展性,可重用性,灵活性等多方面的挑战。
设计模式是为了让程序和软件具有更好的:

  1. 代码重用性 (即: 相同功能的代码,不用多次编写)
  2. 可读性 (即: 编程规范性,便于其他程序员的阅读和理解)
  3. 可扩展性 (即: 当需要增加新的功能时,非常的方便,也叫做 可维护性)
  4. 可靠性 (即: 当我们增加新的功能后,对原来的功能没有影响)
  5. 使程序呈现高内聚,低耦合的特征。

二. 单一职责原则

二.一 基本介绍

一个类,应该只负责一项职责。 如果类 Run 负责两个不同的职责, 如: 公路跑, 天上跑, 那么当职责 1 需求发生改变时,则需要修改 Run 类,
那么在修改的过程中,可能会造成职责 2 执行错误。 所以需要将 Run 类的粒度进行分解, 分解成 公路跑, 天上跑,水里游。

二.二 代码举例

二.二.一 错误的处理

@Slf4j
public class Run {
    public void run(String vehicle) {
        log.info(" {} 在公路上跑", vehicle);
    }
}

测试方法:

@Test
    public void testA() {
        Run run = new Run();
        run.run("小汽车");
        run.run("飞机");
        run.run("鱼");
    }

设计模式的原则(一)_ide

这是不对的.

二.二.二 单一职责

空中飞的一个类:

@Slf4j
public class AirRun {
    public void run(String vehicle) {
        log.info(" {} 在空中飞", vehicle);
    }
}

路上跑的一个类:

@Slf4j
public class LuRun {
    public void run(String vehicle) {
        log.info(" {} 在路上跑", vehicle);
    }
}

水里游的一个类:

@Slf4j
public class WaterRun {
    public void run(String vehicle) {
        log.info(" {} 在水中游", vehicle);
    }
}

测试方法:

@Test
    public void testB() {
        LuRun luRun = new LuRun();
        luRun.run("小汽车");
        AirRun airRun = new AirRun();
        airRun.run("飞机");
        WaterRun waterRun = new WaterRun();
        waterRun.run("鱼");
    }

设计模式的原则(一)_设计模式_02

二.二.三 方法单一职责

方法单一:

@Slf4j
public class RunTotal {
    public void luRun(String vehicle) {
        log.info(" {} 在公路上跑", vehicle);
    }

    public void airRun(String vehicle) {
        log.info(" {} 在空中飞", vehicle);
    }

    public void waterRun(String vehicle) {
        log.info(" {} 在水中游", vehicle);
    }
}

测试方法:

@Test
    public void testC() {
        RunTotal runTotal = new RunTotal();
        runTotal.luRun("小汽车");
        runTotal.airRun("飞机");
        runTotal.waterRun("鱼");
    }

设计模式的原则(一)_ide_03

testA() 不同的交通工具在同一个方法中执行。

testB(), 遵守单一职责, 每一个类进行不同的处理。

testC() 类中每一个方法进行单一职责

二.三 注意事项

  1. 降低类的复杂度, 一个类只负责一项职责
  2. 提高类的可读性,可维护性
  3. 降低变更引起的风险
  4. 通常情况下,应该遵守单一职责原则, 当类中方法数量足够少时,可以在方法级别保持单一职责原则。

三. 接口隔离原则

三.一 基本介绍

一个类对另一个类的依赖,应该建立在最小的接口上.

三.二 代码举例

有五个操作 operation1 operation2 operation3 operation4 operation5

其中, A类 会使用到 1 2,3 接口。 C类会用到 1,4,5 接口。

B 会依赖 A, C 也依赖 D

三.二.一 错误的代码

定义一个接口,有5个接口

public interface InterfaceFive {
     void operation1();
    void operation2();
    void operation3();
    void operation4();
    void operation5();
}

A类:

public class ClassA {
    public void depend1(InterfaceFive interfaceFive) {
        interfaceFive.operation1();
    }
    public void depend2(InterfaceFive interfaceFive) {
        interfaceFive.operation2();
    }
    public void depend3(InterfaceFive interfaceFive) {
        interfaceFive.operation3();
    }
}

B 类:

@Slf4j
public class ClassB implements InterfaceFive{

    @Override
    public void operation1() {
        log.info("B实现操作1");
    }

    @Override
    public void operation2() {
        log.info("B实现操作2");
    }

    @Override
    public void operation3() {
        log.info("B实现操作3");
    }

    @Override
    public void operation4() {
        log.info("B实现操作4");
    }

    @Override
    public void operation5() {
        log.info("B实现操作5");
    }
}

C类:

public class ClassC {
    public void depend1(InterfaceFive interfaceFive) {
        interfaceFive.operation1();
    }
    public void depend4(InterfaceFive interfaceFive) {
        interfaceFive.operation4();
    }
    public void depend5(InterfaceFive interfaceFive) {
        interfaceFive.operation5();
    }
}

D类:

@Slf4j
public class ClassD implements InterfaceFive{

    @Override
    public void operation1() {
        log.info("D实现操作1");
    }

    @Override
    public void operation2() {
        log.info("D实现操作2");
    }

    @Override
    public void operation3() {
        log.info("D实现操作3");
    }

    @Override
    public void operation4() {
        log.info("D实现操作4");
    }

    @Override
    public void operation5() {
        log.info("D实现操作5");
    }
}

方法测试:

@Test
    public void testOne() {
        // 对 A 处理
        ClassA classA = new ClassA();
        classA.depend1(new ClassB());
        classA.depend2(new ClassB());
        classA.depend3(new ClassB());

        // 对 C 处理
        ClassC classC = new ClassC();
        classC.depend1(new ClassD());
        classC.depend4(new ClassD());
        classC.depend5(new ClassD());
    }

设计模式的原则(一)_设计模式原则_04

三.二.二 接口隔离

将接口 InterfaceFive 拆分为独立的几个接口(这里我们拆分成 3 个接口),类A和类 C 分别与他们需要的接口建立 依赖关系。也就是采用接口隔离原则

接口1

public interface Interface1 {
    void operation1();
}

接口2:

public interface Interface2 {
    void operation2();
    void operation3();
}

接口3:

public interface Interface3 {
    void operation4();
    void operation5();
}

类A:

public class NewClassA {
    public void depend1(Interface1 interface1) {
        interface1.operation1();
    }
    public void depend2(Interface2 interface2) {
        interface2.operation2();
    }
    public void depend3(Interface2 interface2) {
        interface2.operation3();
    }
}

类B:

@Slf4j
public class NewClassB implements Interface1,Interface2 {

    @Override
    public void operation1() {
        log.info("B实现操作1");
    }

    @Override
    public void operation2() {
        log.info("B实现操作2");
    }

    @Override
    public void operation3() {
        log.info("B实现操作3");
    }

}

类C:

public class NewClassC {
    public void depend1(Interface1 interface1) {
        interface1.operation1();
    }
    public void depend4(Interface3 interface3) {
        interface3.operation4();
    }
    public void depend5(Interface3 interface3) {
        interface3.operation5();
    }
}

类D:

@Slf4j
public class NewClassD implements Interface1,Interface3 {

    @Override
    public void operation1() {
        log.info("D实现操作1");
    }

    @Override
    public void operation4() {
        log.info("D实现操作4");
    }

    @Override
    public void operation5() {
        log.info("D实现操作5");
    }
}

方法验证:

/**
     将接口 拆分成   1   23   45
     分别去依赖使用,  这样 A 不会拥有 4,5 功能 , C 不会拥有 1,2功能。
     即将 接口的能力进行了约束
     */
    @Test
    public void testTwo() {
        NewClassA classA = new NewClassA();
        classA.depend1(new NewClassB());
        classA.depend2(new NewClassB());
        classA.depend3(new NewClassB());

        // 对 C 处理
        NewClassC classC = new NewClassC();
        classC.depend1(new NewClassD());
        classC.depend4(new NewClassD());
        classC.depend5(new NewClassD());
    }

设计模式的原则(一)_Test_05

三.三 注意事项

接口拆分的粗细度

四. 依赖倒转原则

四.一 基本介绍

  1. 高层模块不应该依赖低层模块,二者都应该依赖其抽象
  2. 抽象不应该依赖细节, 细节应该依赖抽象
  3. 依赖倒转的中心思想是 面向接口编程
  4. 依赖倒转原则是基于这样的设计理念: 相对于细节的多变性,抽象的东西要稳定的多。
    以抽象为基础搭建的架构比以细节为基础搭建的架构要稳定的多。 在 Java中 抽象指的是
    接口或者抽象类,细节指的是具体的实现类
  5. 使用接口或者抽象类的目的是制定好规范,而不涉及任何具体的操作,把展示细节的任务交给他们的实现类去完成。

四.二 代码实例

如实例:

定义一个通知用户的操作

四.二.一 错误实例

邮箱通知:

public class Email {

    public String getInfo() {
        return "构建邮件信息,并进行发送";
    }
}

微信通知:

public class WeiXin {
    public String getInfo() {
        return "构建微信信息,并进行发送";
    }
}

消息发送:

@Slf4j
public class Message {
    public void send(Email email) {
        String info = email.getInfo();
        log.info(">>> 获取邮件信息,并进行发送 {}", info);
    }

    public void send(WeiXin weiXin) {
        String info = weiXin.getInfo();
        log.info(">>> 获取微信信息,并进行发送 {}", info);
    }
}

代码测试:

@Test
    public void sendOneTest() {
        Message message = new Message();
        message.send(new Email());
        message.send(new WeiXin());
    }

设计模式的原则(一)_Java 设计模式_06

四.二.二 依赖转置

定义一个接口, 然后 微信 和邮箱进行实现

public interface SendMessage {

    // 实际是一个对象
    public String getInfo();
}

邮箱:

public class NewEmail implements SendMessage{

    @Override
    public String getInfo() {
        return "构建邮件信息,并进行发送";
    }
}

微信:

public class NewWeiXin implements SendMessage{

    @Override
    public String getInfo() {
        return "构建微信信息,并进行发送";
    }
}

发送:

@Slf4j
public class NewMessage {
    public void send(SendMessage sendMessage) {
        String info = sendMessage.getInfo();
        log.info(">>> 发送 {}", info);
    }
}

测试方法:

/**
    将消息提取成一个接口,  然后邮箱 和微信进行实现。
     */
    @Test
    public void sendTwoTest() {
        NewMessage message = new NewMessage();
        message.send(new NewEmail());
        message.send(new NewWeiXin());
    }

设计模式的原则(一)_Java 设计模式_07

依赖关系传递的三种方案

即有 功能 A, 功能 B, 如何要想 A 使用 B, 则如何处理 ?

  1. 接口实现 A extends B , A implements B
  2. 构造方法传递 public A ( B b )
  3. setter 方法设置 A 中有属性 B , a.setB(b) 再使用

四.三 注意事项

  1. 低层模块尽量都要有抽象类或者接口, 或者两者都有,程序稳定性更好。
  2. 变量的声明类型尽量是抽象类或接口, 这样变量引用和实际对象之间,就存在一个缓冲区,利于程序的扩展和优化。
  3. 继承时遵循里氏替换原则

五. 里氏替换原则

五.一 基本介绍

继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契约,
虽然它不强制要求所有 的子类必须遵循这些契约,但是如果子类对这些已经实现的方法任意修改,就会对整个继承体系造成破坏

继承在给程序设计带来便利的同时,也带来了弊端。比如使用继承会给程序带来侵入性,程序的可移植性降低,
增加对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且 父类修改后,所有涉及到子类的功能都有可能产生故障

里氏替换原则(Liskov Substitution Principle)在 1988 年,由麻省理工学院的以为姓里的女士提出的。

如果对每个类型为 T1 的对象 o1,都有类型为 T2 的对象 o2,
使得以 T1 定义的所有程序 P 在所有的对象 o1 都 代换成 o2 时,程序 P 的行为没有发生变化,
那么类型T2 是类型 T1 的子类型。换句话说,所有引用基类的地 方必须能透明地使用其子类的对象。

在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法

里氏替换原则告诉我们,继承实际上让两个类耦合性增强了,在适当的情况下,可以通过聚合,组合,依赖 来 解决问题

五.二 代码实例

五.二.一 错误代码

基础操作A

public class OperationA {

    public int sub ( int a, int b) {
        return a - b;
    }
}

扩展操作B

public class OperationB extends OperationA{

    @Override
    public int sub(int a, int b) {
       // 对方法进行了改变, 无意重写。 如果不重写的话,当 operationA.sub 方法变化时,所有的子类都会变化。
        return a + b;
    }

    public int div( int a, int b) {
        return a /b;
    }
}

测试方法:

@Test
    public void testOne() {
        OperationA operationA = new OperationA();
        log.info("3-1={}",operationA.sub(3,1));

        OperationB operationB = new OperationB();
        log.info("3-1={}",operationB.sub(3,1));
        log.info("3/1={}",operationB.div(3,1));
    }

设计模式的原则(一)_设计模式原则_08

五.二.二 里氏替换

定义一个空的接口,表示能力

public interface BaseOperation {

}

原操作

public class NewOperationA implements BaseOperation{
    public int sub ( int a, int b) {
        return a - b;
    }
}

扩展操作:

public class NewOperationB implements BaseOperation{
    private NewOperationA operationA = new NewOperationA();

    public int oldSub(int a, int b) {
        // 对方法进行了改变, 无意重写。 如果不重写的话,当 operationA.sub 方法变化时,所有的子类都会变化。
        return operationA.sub(a,b);
    }

    public int sub(int a, int b) {
       // 对其重写的
        return a+b;
    }

    public int div( int a, int b) {
        return a /b;
    }
}

测试方法:

/**
     同时继承一个 BaseOperation 类, 表示接口的能力进行处理。
     */
    @Test
    public void testTwo() {
        NewOperationA operationA = new NewOperationA();
        log.info("3-1={}",operationA.sub(3,1));

        NewOperationB operationB = new NewOperationB();
        log.info("3+1={}",operationB.sub(3,1));
        log.info("3-1={}",operationB.oldSub(3,1));
        log.info("3/1={}",operationB.div(3,1));
    }

设计模式的原则(一)_设计模式_09

五.三 注意事项

六. 开闭原则

六.一 基本介绍

开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则

  1. 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实 现扩展细节
  2. 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化
  3. 编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则

六.二 代码实例

六.二.一 错误实例

画图形接口

public interface Shape {
    int getType();
}

矩形

public class Rectangle implements Shape{

    @Override
    public int getType() {
        return 0;
    }
}

圆形

public class Circle implements Shape{

    @Override
    public int getType() {
        return 1;
    }
}

画图形

@Slf4j
public class DrawShape {

    public void drawShape( Shape shape) {
        if (shape.getType() == 0) {
            drawRectange();
        }else if (shape.getType() == 1) {
            drawCircle();
        }
    }
	// 需要改变
    private void drawCircle() {
        log.info(">>> 画圆");
    }

    private void drawRectange() {
        log.info(">>> 画方形");
    }
}

测试方法:

@Test
    public void oneTest() {
        DrawShape drawShape = new DrawShape();
        drawShape.drawShape(new Rectangle());
        drawShape.drawShape(new Circle());
    }

设计模式的原则(一)_设计模式原则_10

六.二.二 开闭原则

接口:

public interface NewShape {
    int getType();

    void drawShape();
}

矩形:

@Slf4j
public class NewRectangle implements NewShape{

    @Override
    public int getType() {
        return 0;
    }

    @Override
    public void drawShape() {
        log.info(">>> 画方形");
    }
}

圆形

@Slf4j
public class NewCircle implements NewShape{

    @Override
    public int getType() {
        return 1;
    }

    @Override
    public void drawShape() {
        log.info(">>> 画圆形");
    }
}

画图形:

@Slf4j
public class NewDrawShape {

    public void drawShape( NewShape shape) {
        shape.drawShape();
    }
}

测试方法:

@Test
    public void twoTest() {
        NewDrawShape drawShape = new NewDrawShape();
        drawShape.drawShape(new NewRectangle());
        drawShape.drawShape(new NewCircle());
    }

设计模式的原则(一)_设计模式_11

六.三 注意事项

七. 迪米特法则

七.一 基本介绍

  1. 一个对象应该对其他对象保持最少的了解
  2. 类与类关系越密切,耦合度越大。
  3. 迪米特法则又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。也就是说,对于 被依赖的类不管多么复杂,
    都尽量将逻辑封装在类的内部,对外除了提供的public 方法,不对外泄露任何信息。
  4. 迪米特法则还有个更简单的定义, 只与直接的朋友通信。
  5. 直接的朋友: 每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。
    耦合的方式有很多,依赖,关联,组合,聚合等。 其中我们称出现 成员变量,方法参数,方法返回值的类为直接的朋友,而出现在局部
    变量中的类不是直接的朋友。 也就是说,陌生的类最好不要以局部变量的形式出现在类的内部

七.二 代码实例

打印用户和部门信息

七.二.一 错误实例

部门:

@Data
@Builder
public class Dept {
    private Integer id;
    private String name;
}

部门查询列表:

public class DeptManager {
    public List<Dept> findAll() {
        List<Dept> result = new ArrayList<>();

        for (int i = 0;i< 5;i++) {
            result.add(Dept.builder().id(i+1).name("随机部门"+i).build());
        }
        return result;
    }
}

用户:

@Data
@Builder
public class User {
    private Integer id;
    private String name;
}

用户打印时,将部门也进行打印:

@Slf4j
public class UserManager {

    public List<User> findAll() {
        List<User> result = new ArrayList<>();

        for (int i = 0;i< 5;i++) {
            result.add(User.builder().id(i+1).name("随机名称"+i).build());
        }

        return result;
    }


    public void printAll (DeptManager deptManager) {
        // 发现 在这个类里面 有 Dept 类,但这个类并不是 形参,成员变量,方法返回值, 不算是直接朋友。
        List<Dept> deptAll = deptManager.findAll();
        for (Dept dept: deptAll) {
            log.info(">>> 部门 {}", dept);
        }

        List<User> userAll = findAll();
        for (User user: userAll) {
            log.info(">>> 员工 {}", user);
        }
    }
}

测试方法:

@Test
    public void testOne() {
        UserManager userManager = new UserManager();
        userManager.printAll(new DeptManager());
    }

设计模式的原则(一)_Java 设计模式_12

七.二.二 迪米特法则

部门添加一个打印的方法

@Slf4j
public class NewDeptManager {
    public List<Dept> findAll() {
        List<Dept> result = new ArrayList<>();

        for (int i = 0;i< 5;i++) {
            result.add(Dept.builder().id(i+1).name("随机部门"+i).build());
        }
        return result;
    }

    public void printAll () {
        List<Dept> deptAll = findAll();
        for (Dept dept: deptAll) {
            log.info(">>> 部门 {}", dept);
        }
    }
}

用户 通过调用部门,进行部门的打印

@Slf4j
public class UserManager {

    public List<User> findAll() {
        List<User> result = new ArrayList<>();

        for (int i = 0;i< 5;i++) {
            result.add(User.builder().id(i+1).name("随机名称"+i).build());
        }

        return result;
    }


    public void printAll2 (NewDeptManager newDeptManager) {
        newDeptManager.printAll();

        List<User> userAll = findAll();
        for (User user: userAll) {
            log.info(">>> 员工 {}", user);
        }
    }
}

测试方法:

@Test
    public void testTwo() {
        UserManager userManager = new UserManager();
        userManager.printAll2(new NewDeptManager());
    }

设计模式的原则(一)_设计模式_13

七.三 注意事项

  1. 迪米特法则的核心是降低类之间的耦合。
  2. 由于每个类都减少了不必要的依赖,因此迪米特法则只是要求降低类间(对象间)的耦合关系,并不是要求完全没有依赖关系。

八. 合成复用原则

八.一 基本介绍

尽量使用合成/聚合的方式,而不是使用 继承

  1. 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起
  2. 针对接口编程,而不是针对实现编程
  3. 为了交互对象之间的松耦合设计而努力

八.二 代码实例

八.三 注意事项






标签:info,log,原则,void,class,new,设计模式,public
From: https://blog.51cto.com/yueshushu/6506192

相关文章

  • PHP开发:代码风格、重构和设计模式的实践
    一、代码风格和规范:采用一致的代码风格和规范有助于提高代码的可读性和可维护性。我们将介绍一些常见的PHP代码风格指南,如PSR-12(PHPStandardRecommendation),以及一些静态代码分析工具,如PHPCodeSniffer,可以帮助您自动检测代码规范问题。示例代码风格(使用PSR-12):<?phpnamespaceV......
  • 设计模式:适配器模式(论如何把鼠头适配成鸭脖)
    适配器模式(AdapterPattern)有时候也称包装样式或者包装,是一种结构型设计模式,它可以将一个类的接口转换成客户端所期望的另一个接口。适配器模式可以让原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式有三种类型:类适配器模式、对象适配器模式和接口适配器模式......
  • Go设计模式实战--用状态模式实现系统工作流和状态机
    大家好,这里是每周都在陪你进步的网管~!本节我们讲一个行为型的设计模式--状态模式,并通过Golang示例进行实战演示。状态模式(StatePattern)也叫作状态机模式(StateMachinePattern)状态模式允许对象的内部状态发生改变时,改变它的行为,就好像对象看起来修改了它实例化的类,状态模式是一种......
  • 设计模式:适配器模式(论如何把鼠头适配加工成鸭脖)
    定义适配器模式(AdapterPattern)有时候也称包装样式或者包装,是一种结构型设计模式,它可以将一个类的接口转换成客户端所期望的另一个接口。适配器模式可以让原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式有三种类型:类适配器模式、对象适配器模式和接口适配器......
  • Python设计模式-07-装饰模式
    装饰模式是一种结构型设计模式,它允许我们动态地将行为添加到对象中,而不需要使用继承。装饰模式通常包括以下几个角色:抽象组件(Component):定义了一个接口,用于被装饰对象和装饰器共同实现。具体组件(ConcreteComponent):实现了抽象组件定义的接口,并提供了默认的行为。抽象装饰......
  • Python设计模式-17-外观模式
    外观模式是一种结构型设计模式,它为复杂的子系统提供了一个简单的接口,从而隐藏了子系统的复杂性。外观模式通常包括以下几个角色:外观(Facade):提供了一个简单的接口,用于访问子系统中的一组接口。子系统(Subsystem):实现了子系统的功能,并处理外观对象指派的任务。下面是一个简单......
  • Python设计模式-18-中介模式
    中介模式是一种行为型设计模式,它允许对象之间通过一个中介对象进行通信,从而减少对象之间的直接耦合。中介模式通常包括以下几个角色:中介者(Mediator):定义了一个接口,用于与各个同事对象通信,并协调它们之间的交互。具体中介者(ConcreteMediator):实现了中介者定义的接口,并协调各个......
  • Python设计模式-19-备忘录模式
    备忘录模式是一种行为型设计模式,它允许我们在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。备忘录模式通常包括以下几个角色:发起人(Originator):定义了一个接口,用于创建备忘录对象和恢复对象状态。备忘录(Memento):存储发起人对象的内部状态。管理......
  • Python设计模式-20-迭代器模式
    迭代器模式是一种行为型设计模式,它允许我们按照顺序访问一个聚合对象中的元素,而不需要暴露该对象的内部表示。迭代器模式通常包括以下几个角色:迭代器(Iterator):定义了一个接口,用于按照顺序访问聚合对象中的元素。具体迭代器(ConcreteIterator):实现了迭代器定义的接口,并维护了当......
  • Python设计模式-21-解释器模式
    解释器模式是一种行为型设计模式,它定义了一种语言,用于解释和执行特定的任务。解释器模式通常包括以下几个角色:抽象表达式(AbstractExpression):定义了一个接口,用于解释和执行特定的任务。终结符表达式(TerminalExpression):实现了抽象表达式定义的接口,并表示语言中的终结符。......