设计模式学习笔记

设计模式学习笔记

设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

开闭原则

image-20230929215756325

对拓展开放,对修改关闭,程序实现多运用接口和抽象类

里氏代换原则

image-20230929222105535

image-20230929223440920

当子类需要重写父类的方法时,需要定义一个接口定义重写的方法,父类与子类都实现接口,避免子类重写父类方法导致错误

依赖倒转原则

在模块之间进行交互时,高层模块应依赖低层模块的接口与抽象

例如Controller层的实各个类中使用的是Service层的service接口,而不是直接依赖service层中的Impl实现类

image-20230929225224790

接口隔离原则

image-20230929230056285

image-20230929230613709

迪米特法则

image-20230929231158585

在两对象之间插入中介的方式减少耦合

合成复用原则

image-20230929232605904

减少实现过程中采用的继承,尽量使用组合和聚合

创建型模式(怎样创建对象)

单例模式

创建类对象方式

image-20230930111132300

静态代码块

image-20230930111708964

调用方法时创建对象

image-20230930112256938

image-20230930112517221

双重检查锁

image-20230930113332172

image-20230930113656108

静态内部类(推荐)

image-20230930114206494

枚举(推荐)

image-20230930114358562

image-20230930114456398

破坏单例模式

序列化+反射

序列化方式

image-20230930154744578

image-20230930155048540

反射方式

image-20230930155440435

破坏单例模式的解决方案
序列化解决

image-20230930155658441

反射解决

image-20230930160644118

单例设计模式应用——RunTime类

image-20230930161530538

工厂模式

简单工厂模式

image-20230930165029931

静态工厂模式

image-20230930165324661

工厂方法模式

通过定义工厂类的接口,对factory对象的通用方法进行定义

image-20231001104435560

抽象工厂模式

一个抽象工厂会定义多个不同的生产产品的方法

image-20231001111533242

image-20231001111755865

即AmericanDessertFactory工厂中存在产品AmericanCoffee和MatchaMousse,而IntalyDessertFactory工厂中存在产品Tiramisu和LatteCoffee

应用场景

image-20231001112211049

工厂模式拓展(简单工厂+配置文件)

image-20231001113754343

建造者模式

抽象builder类定义产品组装方法

image-20231001152051803

指挥者类控制组装过程

image-20231001152129944

拓展——内部builder

image-20231001152515286

image-20231001152533671

原型模式

image-20231001151956950

创建型模式对比

image-20231001151904253

结构型模式(怎样创建结构)

代理模式

通过构建代理类,在不改变火车站基本买票功能的基础上,实现了代售点卖票这一功能的增强

静态代理

通过代售点代理将一个火车站买票主题与客户端分离,使客户端不能直接访问火车站买票主题,即用户不需要去火车站即可购买到票

image-20231002134626732

JDK动态代理

通过JDK的Proxy类构建代理类,注意此方法用到了匿名内部类IvocationHandler,对sellTickets接口的方法进行了映射

image-20231002140554629

image-20231002140609859

image-20231002140659639

CGLIB代理

JDK方式使用接口代理,当没有实现接口时,使用CHLIB代理方式,不同于JDK形式基于反射实现,CGLIB基于继承实现

image-20231002142750912

image-20231002142812544

image-20231002142829005

代理模式对比

image-20231002142926667

适配器模式

将原来的接口转化为需要的另一个接口

类适配器模式

此适配器定义了一个类继承了要进行适配的类TFCardImpl,所以此类能够使用TFCardImpl中的方法,读取TF卡中的数据。

此类实现了目标接口SDCard,所以此类可以直接使用SDCard接口来与Computer类进行交互

实现了读取TFCard中的数据,用于只能读取SDCard计算机

image-20231002173423248

对象适配器

TFCard接口作为成员变量,使用构造方法传入,不再继承TF接口

image-20231002181548836

image-20231002181827043

装饰者模式

image-20231002184017962

image-20231002184218745

image-20231002184629863

与静态代理区别

image-20231002185030377

桥接模式

将接口作为抽象类的成员变量,使用构造方法引入接口,从而实现抽象类与接口分离,便于分别实现拓展

image-20231004200053128

image-20231004200157241

外观模式

通过创建外观类,聚合各个功能的成员变量,使用构造方法引入,调用各个功能的方法

注意与代理模式进行区分:代理模式是通过继承的方式,来对功能进行增强,外观模式是通过使用成员变量调用方法,对外界提供统一的功能使用类

image-20231004202017919

组合模式

构建目录等级系统,类似于二叉树

菜单实现类中另外聚合了抽象的根节点,此时它就可以用于实现多层菜单

image-20231007191159471

image-20231007191610714

image-20231007191713487

分类

透明组合模式:方法全都定义在抽象根节点中

安全组合模式:抽线根节点中不会定义任何方法,而是在菜单类中定义

享元模式

image-20231007195342273

image-20231007195810160

image-20231007195932257

BoxFactory使用单例设计模式创建,初始化时存储图形信息,每次需要访问图形时,只需要调用BoxFactory调用对应方法

行为型模式(怎样实现功能)

模板方法模式

image-20231007202009385

策略模式(替代多重if-else)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

多重if-else与策略模式对比

策略模式是一种行为型设计模式,它可以用来消除大量的if-else语句,提高代码的可维护性和可扩展性。策略模式将不同的算法封装到不同的类中,使得它们可以相互替换,而不影响客户端代码的使用。

以下是策略模式如何替代if的示例:

假设我们有一个计算器程序,可以对两个数字进行加、减、乘、除运算。使用if-else语句实现如下:

public class Calculator {
    public int calculate(int a, int b, String operator) {
        if (operator.equals("+")) {
            return a + b;
        } else if (operator.equals("-")) {
            return a - b;
        } else if (operator.equals("*")) {
            return a * b;
        } else if (operator.equals("/")) {
            return a / b;
        } else {
            throw new IllegalArgumentException("Invalid operator: " + operator);
        }
    }
}

使用策略模式重构后的代码如下:

首先定义一个接口:

public interface Operation {
    int apply(int a, int b);
}

然后实现不同的算法类:

public class AddOperation implements Operation {
    @Override
    public int apply(int a, int b) {
        return a + b;
    }
}

public class SubOperation implements Operation {
    @Override
    public int apply(int a, int b) {
        return a - b;
    }
}

public class MulOperation implements Operation {
    @Override
    public int apply(int a, int b) {
        return a * b;
    }
}

public class DivOperation implements Operation {
    @Override
    public int apply(int a, int b) {
        return a / b;
    }
}

最后在Calculator类中使用策略模式:

public class Calculator {
    private Map<String, Operation> operations = new HashMap<>();

    public Calculator() {
        operations.put("+", new AddOperation());
        operations.put("-", new SubOperation());
        operations.put("*", new MulOperation());
        operations.put("/", new DivOperation());
    }

    public int calculate(int a, int b, String operator) {
        Operation operation = operations.get(operator);
        if (operation == null) {
            throw new IllegalArgumentException("Invalid operator: " + operator);
        }
        return operation.apply(a, b);
    }
}

使用策略模式后,我们可以轻松地添加新的算法类,而不需要修改原有的代码。这样可以使代码更加灵活和易于维护

责任链模式

image-20231008190523347

image-20231008190619312

image-20231008191428521

状态模式

观察者模式

image-20231008210617894

image-20231008210645415

image-20231008210757350

观察者模式的核心思想是将被观察者和观察者解耦,使它们之间的依赖关系变得松散。被观察者只需要维护一个观察者列表,并在状态变化时通知观察者,而不需要关心具体的观察者是谁以及如何处理通知。观察者只需要注册到被观察者的观察者列表中,并实现自己的业务逻辑,不需要关心被观察者的具体实现。

JDK提供的观察者实现

image-20231008211215343

中介者模式

image-20231008212516559

image-20231008212542078

image-20231008212712566

image-20231008212656217

image-20231008212829983

迭代器模式

image-20231008213732459

image-20231008214009249

image-20231008214045781

容器实现类

image-20231008214129895

image-20231008214230741

访问者模式

当数据结构中使用到元素,可以在元素改变时不会对数据结构产生影响

当需要添加用到元素的功能的时候,可以使用访问者进行拓展

image-20231009192412769

备忘录模式

提供状态恢复机制,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态

白箱备忘录

其中GameRole为发起人,类中提供saveStateMeMento和rollback方法用于保存当前状态和进行状态回滚

RoleStateMemento中定义了与GameRole相同的成员变量,用于记录成员状态,RoleStateCareTaker为管理者,实现GameRole状态的回滚

image-20231009195356287

黑箱备忘录

不再创建RoleStateMemento类,而是在GameRole中创建RoleStateMemento内部类,对外提供Memento接口供RoleCareTacker使用

image-20231009200340893
中…(img-eD1kqXTP-1718435493202)]

备忘录模式

提供状态恢复机制,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态

白箱备忘录

其中GameRole为发起人,类中提供saveStateMeMento和rollback方法用于保存当前状态和进行状态回滚

RoleStateMemento中定义了与GameRole相同的成员变量,用于记录成员状态,RoleStateCareTaker为管理者,实现GameRole状态的回滚

[外链图片转存中…(img-cwKSTVMd-1718435493203)]

黑箱备忘录

不再创建RoleStateMemento类,而是在GameRole中创建RoleStateMemento内部类,对外提供Memento接口供RoleCareTacker使用

[外链图片转存中…(img-1O1jygfd-1718435493203)]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值