设计模式

软件设计六大原则:

开闭原则(Open Close Principle):

概述:

对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码。
所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。

里氏代换原则(Liskov Substitution Principle):

概述:

里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。
子类可以扩展父类的功能,但不能改变父类原有的功能。

依赖倒转原则(Dependence Inversion Principle):

概述:

这个是开闭原则的基础。
通过要面向接口的编程来降低类间的耦合性,对接口编程,依赖于抽象而不依赖于具体。

实际应用:

spring的IOC

单一职责原则:

概述:

规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分

接口隔离原则(Interface Segregation Principle):

概述:

使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。
所以上文中多次出现:降低依赖,降低耦合。

迪米特法则(最少知道原则)(Demeter Principle):

概述:

如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。

缺点:

过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。

合成复用原则(Composite Reuse Principle):

概述:

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

设计模式:

概述:

代码设计经验的总结,创建型、结构型和行为型3大类,一共23种设计模式。
常用设计模式:
    简单工厂、工厂方法模式、抽象工厂(开闭原则)、建造者、单例、适配器、装饰器、策略、模板方法、观察者模式

创建型模式:

概述:

对对象的创建进行研究。

工厂模式:

简单工厂模式(Simple Factory):
定义一个用以创建对象的工厂, 根据不同的条件(参数)生成不同的对象。在golang中定义NewXXX函数来初始化相关类。
在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern)。
工厂方法模式(Factory Method):
而“工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。
用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。
抽象工厂模式(Abstract Factory):
是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。

建造者模式(Builder):

指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。(子类有具体不同的实现)

原型模式(Prototype):

一种创建型模式,用于创建重复的对象,同时又能保证性能。实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。

单例模式(Singleton):

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

结构型模式:

概述:

描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。

外观模式(Facade):

概述:
创建一个类用于为程序库、 框架或其他复杂类提供一个简单的接口。

适配器模式(Adapter):

概述:
增加了一个类,用于将一个类的接口转换成客户希望的另一个接口。
结构:
目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。
适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。
适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
缺点:
适配器编写过程需要结合业务场景全面考虑,可能会增加系统的复杂性。
增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。
实际场景:
Spring MVC中的HandlerAdapter适配器,适配 Controller

代理模式(Proxy):

概述:
由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
结构:
抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
缺点:
代理模式会造成系统设计中类的数量增加,在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
进阶:
动态代理
实际场景:
Spring AOP 功能的实现。

装饰模式(Decorator):

概述:
动态的给一个对象添加一些额外的功能

桥模式(Bridge):

概述:
可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构,从而能在开发时分别使用。就是一个A类调用接口,关联到其他的类B。
某些类型由于自身的逻辑,它具有两个或多个维度的变化,于是将抽象部分与实现部分分离,使它们都可以独立的变化。(避免多个继承)
类似于多继承方案,但是多继承方案往往违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
遵循了里氏替换原则和依赖倒置原则,最终实现了开闭原则,对修改关闭,对扩展开放。
示例:
p.setLayout(new GridLayout(1, 1));
                p.setBorder(BorderFactory.createTitledBorder("女士皮包"));

组合模式(Composite):

概述:
组合最主要的功能是在整个树状结构上递归调用方法并对结果进行汇总。
将对象组合成树形结构以表示“部分-整体”的层次结构。
在组合模式中,整个树形结构中的对象都属于同一种类型,带来的好处就是用户不需要辨别是树枝节点还是叶子节点,可以直接进行操作,给用户的使用带来极大的便利。
用途:
比如总店和分店,在总店购买时,积分也一样累加在分店卡上。

享元模式(Flyweight):

概述:
会将不同对象的相同数据进行缓存以节省内存。
运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。

行为型模式:

概述:

在对象的结构和对象的创建问题都解决了之后,就剩下对象的行为问题了。

模板方法模式(Template Method):

概述:
一种行为设计模式, 它在基类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中(重写)。行为(次数,数量)由父类控制,子类实现。
比如sms和邮件都有着getMessage、sendNotification等方法
适合场景:
一些方法通用,却在每一个子类都重新写了这一方法。
实际场景:
spring自带的 jdbcTemplate 、 hibernateTemplate 等以 Template 结尾的对数据库操作的类

观察者模式(Observer):

概述:
又名发布-订阅(Publish/Subscribe)模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
具体做法:
写一个基类,包含基本的添加、解除、通知等需要的方法,其中通知方法遍历使用被观察者类的被通知方法;
然后写一个继承的观察者类,里面包括传入信息,执行通知方法的方法;
再写几个被观察者类,有被通知方法;
                  最后实例时,添加被观察者到观察者的列表中,输入msg即可触发通知方法。

状态模式(State):

概述:
对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,不同的状态对象,其行为是不同的。
更注重状态变化时,有不同的行为。
示例:
type computer interface {
    setPrinter(printer)         设置不同的printer后,有不同的print行为。  
    print()
}

策略模式(Strategy):

概述:
使用算法的责任和算法本身分割开来,委派给不同的对象管理。
遵循开闭原则。
与状态模式比较:
比较类似,更注重使用不同的策略,行为全部改变。
示例:
缓存类的一个属性为算法接口,这个算法接口可以用不同的算法实现。

责任链模式(Chain of Responsibility):

概述:
允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
应用场景:
中间件、拦截器

命令模式(Command):将一个请求封装成为一个对象, 使可以用不同的请求对客户进行参数化。命令模式使得调用者和接收者不直接交互。

访问者模式(Visitor):将算法与其所作用的对象隔离开来。允许你在不修改已有代码的情况下向已有类层次结构中增加新的行为。
func (obj *square) accept(v visitor){
    v.visitForSquare(obj)           # visitor是新的行为类,拥有visitForSquare方法,该方法能访问到obj,增加行为
}

中介者模式(Mediator):能让你减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作。
飞行器驾驶员之间不会通过相互沟通来决定下一架降落的飞机。 所有沟通都通过控制塔台进行。

备忘录模式(Memento):允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。在需要在对象上实现撤销-重做操作时非常实用。常见做法是用缓存存下状态。restorememento方法

迭代器模式(Iterator):让你能在不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素。

解释器模式(Interpreter):在正则表达式、XML文档解释等领域还是得到了广泛使用。        
posted @ 2021-12-27 20:54  心平万物顺  阅读(40)  评论(0编辑  收藏  举报