Git Product home page Git Product logo

design-pattern-learning's Introduction

design-pattern-learning

design-pattern-learning

##设计模式学习笔记

一.设计模式七大原则 1.单一职责(Single Responsibility Principle) 一个类和方法应只负责某一项职责 2.接口隔离(Interface Segregation Principle) 一个类对另一个类的依赖应建立在最小的接口上 3.依赖倒置(Dependence Inversion Principle) 面向接口编程 4.里氏替换(Liskov Substitution Principle) 所有使用基类的地方必须能透明的使用其子类;子类中尽量不要重写父类的方法,会破坏继承体系; 适当的情况下,采用聚合,依赖和组合方式解决 5.开闭原则(Open Close Principle) 对扩展开放对修改关闭,尽可能的少修改代码 6.迪米特法则(Demeter Principle) 最少知道原则,一个类应该对自己依赖的类知道的越少越好,只与直接朋友通信(成员变量,方法参数,方法返回值) 7.合成复用(Composite Reuse Principle) 尽量使用合成/聚合的方式,而不是继承

二.设计模式

5种创建型设计模式: 关注如何创建对象,将对象的创建和使用相分离,分为:单例模式、工厂方法模式、抽象工厂模式、原型模式、建造者模式 7种结构型设计模式: 关注如何组合各种对象获得更好、更灵活的结构,分为:适配器模式、桥接模式、组合模式、装饰器模式、代理模式、享元模式、外观模式 11种行为型设计模式: 涉及算法和对象间的职责分配,一组对象间协调完成一个整体的任务,分为:责任链模式、命令模式、解释器模式、迭代器模式、中介模式、 备忘录模式、观察者模式、模板方法模式、状态模式、策略模式、访问者模式

1)5种创建型设计模式

1.单例模式(8种) 一个类只有一个实例,并提供单个的全局访问点(静态方法) 饿汉式(静态常量) 饿汉式(静态代码块) 懒汉式(线程不安全) 懒汉式(线程安全,同步方法) 懒汉式(线程安全,同步代码块) 双重校验锁 静态内部类 枚举类 使用场景: 频繁使用和创建的对象、创建对象耗时或资源过多的对象(重量级对象)、工具类对象、频繁访问数据库或文件的对象(如数据源、session工厂等) 2.工厂方法模式 专门的工厂类来创建对象 工厂方法模式(简单工厂模式、工厂方法模式、静态工厂方法模式) 3.抽象工厂模式(简单工厂模式+工厂方法模式的整合,抽象出更加抽象的接口) 4.原型模式(原对象的克隆体,需要区分深拷贝和浅拷贝)
实现方式: 1.实现Cloneable接口,重写Object类的clone方法(浅拷贝,若要实现深拷贝,需要把依赖的对象一层层复制完毕即可) 2.序列化与反序列化实现(深拷贝) 5.建造者模式(将复杂对象的创建过程封装起来,对外屏蔽具体的创建过程,对外提供一个build方法即可)
角色组成: product(产品)、抽象建造者AbstractBuilder(抽象类或接口)、具体建造者ConcreteBuilder(建造步骤,以方法区分)、 指挥者(director,负责串联具体建造流程)

2)7种结构型设计模式

1.适配器模式 让两个不兼容的类可以协调工作,称之为Adapter或Wrapper 类的适配器模式 Adapter类,通过继承src类(被适配者),实现dest(目标对象)接口,实现src->dest的适配 对象的适配器模式 Adapter类,通过聚合src类(被适配者),实现dest接口,实现src->dest的适配 接口的适配器模式 Adapter类,通过继承一个实现src接口的抽象类,来实现自己想要实现的方法即可

2.桥接模式(基于类的最小设计原则,通过使用封装、聚合及继承等行为,让不同的类承担不同的职责.把抽象与实现行为分离开来,保证各个功能的独立性和扩展性) 使用步骤: 定义一个聚合了目标接口的抽象类,此类中增加实例方法,仅是调用接口中的方法,通过继承抽象类的子类,重写接口方法和目标接口的实现类实现业务需求,达到将抽象类和 目标接口桥接起来的作用,减少类爆炸 注意:重点在于识别出两个独立变化的维度(抽象和接口),替代多重继承

使用场景: JDBC驱动程序; 银行转账(转账分类: 网上转账,柜台转账,ATM转账(抽象) 转账用户类型: 普通客户,银卡客户,金卡客户(接口)); 消息发送(消息类型: 即时消息,延时消息(抽象) 消息分类: 手机消息,QQ消息,微信消息,邮件消息等(接口));

3.装饰器模式(动态给对象增加新功能,也体现了OCP原则) 使用步骤: 装饰器与被装饰者实现同一个接口或继承同一个抽象类,并持有被装饰对象的实例(或抽象),在装饰器类中,通过在调用原目标的方法基础之上, 重写原方法并额外增加新功能

4.组合模式(部分-整体模式,依据树形结构来组合对象) 包含对象: Component(抽象类或接口)、Leaf(叶子节点,没有子节点)、Composite(非叶子节点,继承或实现Component,实现子部件的相关操作,比如add,remove等)

5.外观模式(过程模式或门面模式,提供一个统一的访问入口,屏蔽其他子系统的细节,其他子系统可以定义一个高层接口.来定义公共行为)

6.享元模式(Flyweight,运用共享技术有效的支持大量细粒度对象) 使用场景: 系统底层开发,解决性能问题 经典场景: String常量池、数据库连接池、缓冲池等等 外部状态: 随环境改变而改变,不可共享的状态 内部状态: 不随环境改变而改变,可共享的状态,一旦定义好之后就不可更改 使用步骤: 享元角色(产品的抽象,定义外部状态)、具体的享元角色(定义内部状态和如何使用外部状态)、享元工厂类(池,不包含不可共享角色)、不可共享角色

7.代理模式(通过代理对象访问目标对象,扩展目标对象的功能) 目标对象:远程对象、开销大的对象、需要安全控制的对象 分类: 静态代理、动态代理(jdk代理,接口代理)和Cglib代理 使用场景: 静态代理(类似于装饰器模式); 静态代理模式组合被代理对象,装饰器模式聚合被代理对象 动态代理(基于接口实现的代理,代理对象不需要实现接口,被代理对象需要实现接口,借助Proxy类的newProxyInstance方法); Cglib代理(基于子类实现的代理,底层原理是通过字节码处理框架ASM来转换字节码,生成新的类); Cglib使用步骤: 1.1 引入ASM框架相关依赖包 asm.jar、asm-commons.jar、asm-tree.jar、cglib-2.2.jar 1.2 在内存中动态的创建子类(不能为final,否则会包IllegalArgumentException),即创建代理类,实现MethodInterceptor接口,重写 intercept()方法,实现被代理对象的方法调用 1.3 不会执行目标对象额外的业务方法(final/static修饰)
几种常见的代理模式变种: 防火墙代理; 缓存代理; 远程代理; 同步代理

3)11种行为型模式

1.模板方法模式(公共的处理逻辑,封装到抽象类中)

使用步骤: 1.1 定义抽象模板和所有的抽象方法 1.2 将公共部分的方法修改成实例方法,并填充处理逻辑,差异性方法定义成抽象方法,交给子类去实现,然后按照逻辑把实例方法和差异性方法 封装到统一的方法入口; 1.3 子类实现抽象差异方法,填充处理逻辑 1.4 客户端调用抽象的统一方法入口

2.命令模式(一个请求封装为一个对象,以便使用不同的参数来表示不同的请求(命令),同时支持可撤销) 包含对象: 调用者(命令发布者)、接收者(命令接收者)、命令 使用步骤: 1.1 定义命令接口,包含执行和撤销方法 1.2 定义命令接受者及其行为 1.3 定义具体的命令执行对象,聚合目标命令接收者 1.4 定义命令发布者(调用者),聚合多个命令,包含设置命令、执行命令和撤销命令的操作 1.5 客户端创建命令接收者(命令执行者) --> 创建命令对象 --> 将命令对象设置到调用者 --> 调用者调用指定命令完成任务

3.访问者模式(不改变数据结构的前提下,定义作用于这些元素的新的操作,将数据结构和数据操作分离,解决数据结构和操作的耦合性问题) 原理: 在被访问者的类里增加一个对外提供接待访问者的接口 应用场景: 需要对一个对象结构中的对象进行很多不同的操作(这些操作没有关联),同时需要防止这些操作"污染"这些对象的类时 双分派: 不管类怎么变化,我们都能找到期望的方法运行. 双分派意味着得到执行的操作取决于请求的种类和两个执行者的类型 适用场景: 一个系统有比较稳定的数据结构,但是功能需求经常变化

4.迭代器模式(提供一种遍历集合的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示:即不暴露内部结构) 包含对象: 迭代器接口,具体迭代器,聚合接口,具体聚合类(依赖唯一迭代器),共同输出对象(OutPutImpl)

5.观察者模式 原理: 对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化 角色职责: Subject: 主题 --> 观察者注册,移除,推送观察者或者观察者获取数据来源 Observer 观察者 --> 接收输入 应用场景: 用户订牛奶(奶站Subject,用户Observer)、第三方网站订阅气象站天气(气象站Subject,第三方网站Observer)

6.中介者模式 原理: 用一个中介对象来封装一系列对象的交互.中介者使各个对象之间不需要显示的相互引用,从而使其耦合松散,并且可以改变对象间的交互. 角色: Mediator 抽象中介者,ConcreteMediator 具体中介者,Colleague 抽象同事类,ConcreteColleague 具体同事类(都依赖于中介者)

7.备忘录模式 原理: Memento在不破坏封装性的前提下,捕获对象的内部状态,将对象的内部状态提取到外部保存,以便于后续需要从外部恢复对象状态 角色: originator: 对象(需要保存状态的对象)、Memento: 备忘录对象,负责保存好记录,即originator状态、CareTaker: 守护者对象对象, 负责保存多个备忘录对象,使用集合管理,提高效率 说明: 如果想要保存多个备忘录对象的不同时间的状态,使用HashMap<String,集合>保存即可 缺点; 类的成员变量过多,比较占用资源,且每次保存会消耗一定的内存 使用场景: 后悔药,游戏存档,ctrl+Z,后退,数据库事务管理等,备忘录模式可以配合原型模式一起使用,避免每次new对象

8.解释器模式 原理: 给定一个语言(表达式),定义他的语法一种表示,并定义一个解释器,通过解释器来执行语言(表达式) 角色: Context: 环境,包含解释器之外的所有信息; AbstractExpression:抽象表达式,声明一个抽象的解释操作 TerminalExpression: 终结符表达式,实现语法中终结符相关的解释操作; NonTerminalExpression: 非终结符表达式,实现语法中非终结符相关的解释操作; 说明: Context和TerminalExpression是通过客户端传入信息的 使用场景: 需要解释的语言表示为一个抽象语法树;一些重复出现的问题可以用简单的语言来表达;一个简单的语法需要解释的场景;编译器;正则表达式等

9.状态模式 原理: 主要用来解决对象在多种状态转换时,需要对外输出不同行为的问题.状态和行为是一一对应的,状态之间可以相互转换 角色: Context类:环境角色,用于维护State实例,这个实例定义当前状态 State: 抽象状态角色,定义一个接口封装与Context的一个特点接口相关行为 ConcreteState: 具体状态角色,每个子类实现一个与Context的一个状态相关行为 说明: 当一个对象的内在状态发生了变化,允许改变其行为. 使用场景: 一个事件/对象有多种状态,状态之间会相互转换,不同的状态有不同的行为时,可以考虑使用

10.策略模式 原理: 定义算法蔟,分别封装起来,让他们之间可以相互替换,客户不用关心算法的具体细节,只是指定某一种算法即可 角色: IStrategy: 策略接口,指定策略行为 ConcreteStrategy: 具体策略类,定义详细的策略行为,不同的策略类有不同的策略 StrategyContext: 策略上下文,组合/聚合策略,将调用上下文中的方法转移到具体的策略行为类中 使用场景: 替换多重转移(if else if else)

11.责任链模式(Chain of Responsibility Pattern)
原理: 又叫职责链模式,为请求创建了一个接受者对象的链.请求发送者和请求接收者解耦;每个接收者对象都包含下一个接受者对象的引用,如果当前不能 处理,那么则将请求传递给下一个接收者对象,以此类推. 角色: Request: 请求 Handler: 抽象处理者(接收者对象抽象),定义了一个处理请求的接口,同时包含其他的Handler(下一个Handler) ConcreteHandlerA,B: 具体的接收者对象,用来处理当前请求,如不能处理,将当前请求递交给下一个接收者对象,形成职责链 说明: 请求和处理分开,解耦,提高了系统灵活性;简化了对象,使对象不用知道链的结构;责任链不能太长,会影响性能,一般需要设置最大数量 使用场景: 多个对象/多级对象处理一个请求(请假,加薪流程;Tomcat中对Encoding的处理;拦截器)

design-pattern-learning's People

Contributors

yyz0225 avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.