您的位置:首页 > 其它

设计模式——分析与感悟

2017-06-05 10:04 267 查看

本文包括四个方面:设计要求、设计原则、设计模式、感悟

设计要求

1.可扩展,可维护,可复用,灵活性好

2.松耦合

原则

1.单一职责:就一个类而言,应该仅有一个引起它变化的原因。如果对于一个类来说,可以从多个动机去改变这个类(又想访问数据库,又想处理数据多一些内容),那么这个类就具有超过一个的职责。

 

2.开放-封闭原则:软件实体(类,模块,函数等)应该可以扩展,不可以修改。最初编写代码时,假设变化不会发生,当变化发生时,就创建抽象来隔离以后发生的同类变化。所以说,尽早的发现变化,就越容易抽象,遵守这个原则。

 

3.依赖倒转原则:1).高层模块不依赖底层模块,二者都依赖抽象。实际上就是高层和底层二者都针对接口编程,谁也不管谁具体的实现,都能灵活自如。2).抽象不依赖细节,细节依赖于抽象。就是抽象自行定义能得到对应功能,但是细节必须根据抽象来实现(实现接口,或继承抽象类)

 

4.里氏代换原则:当一个软件实体中用的父类被子类替换,软件感觉不出来区别,仍能运行。其实这个原则体现了继承,多态的概念。也体现于开放-封闭原则有某种关联。

 

5.迪米特法则:如果两个类不必彼此直接通信,那么就不应该发生直接的相互作用。如果一个类要调用另一个类的方法的话,可以通过第三者转发这个调用。实际上就是,实现类和实现类直接通信没有必要就不该相互作用。若需要调用方法,可以通过接口来调用。间接的体现了依赖倒转原则。说的简单点就是通过接口来相互通信

 

6.合成/集合复用原则:尽量利用合成/集合,尽量不要使用类继承。当他们确实是“is a”关系采用继承。利用这个原则会使类继承层次保持较小规模,避免增长为庞然大物。

 

7.敏捷开发原则:不要为代码添加基于猜测的,实际不需要的功能

设计模式

1.简单工厂模式:直接或提供参数获取对象,而不管内部如何实现。



2.策略模式:当在不同时间需要应用不同的业务算法,就可以用策略模式封装算法。若再跟简单工厂结合,就可以将客户端与业务逻辑代码耦合度降到更低。



3.装饰模式:动态地给一个对象添加一些额外的职责。可以理解为:为已有功能动态的添加更多功能的一种方式。



4.代理模式:为对象提供代理以控制对象的访问。就是提供一种间接性,不直接访问对象,可以利用这种间接性附加功能。



5.工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。就是让创建什么对象交给子类决定。



6.原型模型:用原型具体的实例指定需要创建的对象的种类,用且通过拷贝这些原型创建新的对象。其实就是从一个已有的对象,创建一个和他一样的对象。其实就是克隆。



7.模板方法模式:定义一个操作中算法(逻辑步骤)的骨架,对其中某些步骤由子类类具体实现。这个模式使得子类不改变算法结构就可重定义某些特定步骤。



8.外观模式:为子系统中的一组接口(类)提供一个一致的界面,此界面可以通过接口实现。通过界面可以使使用子系统可以更加的容易。其实就是将子系统封装起来,通过一个对外的类或接口来提供子系统的功能。



9.建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建出不同的表示。这个就是以一个特定顺序的几个步骤构建一个对象,而步骤的详细实现由具体实现决定,这样构建出来的对象,都是通过特定顺序步骤的,但是可以得到不同的表示。



10.观察者模式(发布-订阅模式):定义了一种一对多的依赖关系,让多个观察者监听一个主题对象。当主题对象发生变化时,通知所有观察者做出响应。就是一个对象里维护了多个观察者对象,当某种因素变化时,调用通知方法通知所有观察者,其实就是调用每个观察者的对应方法。



11.抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。其实就是相对于工厂方法在一个具体工厂类中可以提供多个产品,而工厂方法就提供一个产品。



12.状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。其实就是维护一个状态工作类,调用行为方法,行为方法调用工作类的方法。不同的状态,工作类就不同。这样,工作类不同,行为就会不同。



13.适配器模式:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原来由于接口不兼容而不能一起工作的那些类可以一起工作。



14.备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象回复到原先保存的状态。其实就是另一个类里面也有被保存类需要保存的成员变量,这样就可用另一个类来保存需要被保存的类的相应的状态了。



15.组合模式:将对象组合成树形结构以表示“部分——整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。其实是让整体呈个树状,每个树枝有一个集合维护自己的树枝和树叶。树枝和树叶都继承同一个类或实现同一个接口,这样可以通过父类或接口操作所有的树枝和树叶。



16.迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。



17.单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。实现:让类自身负责保存它的唯一实例,并将构造方法私有,保证没有其他实例可以被创建,统一提供一个可以访问实例的方法。



18.桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立的变化。可以这么理解:就是利用合成/聚合将多角度的抽象分类组织起来,一起表示。同时各个抽象分类可以独立的变化。



19.命令模式:将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。其实就是增加一个中间类,用来连接客服端类与提供服务的类,将客户的请求通过中间类传达给服务类。


 
20.职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。

其实就是接收的处理者内部合成/聚合了一个其他的处理者,自己没法处理时,就调用内部维护的处理者处理。



21.中介者模式:用一个中介者对象来封装一系列的对象交互。中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。这个模式的重点是每个对象都不需要知道其他的对象,只知道通过中介者发送和接收响应消息。中介者知道哪些对象需要交互,如何交互。



22.享元模式:运用共享技术有效地支持大量细粒度的对象。实际上就是外部状态(对象私有的,无法共享),每个对象都各自创建拥有。内部状态(不随环境变化,可以共享的),每个对象可以相互引用共享。



23.解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。实际上就是写解释器的文法类,每一个文法都要定义一个类。根据需要解释的句子选择不同的文法类来解释。



24.访问者模式:表示一个作用于某对象结构中的各个元素(实际上就是元素本身也可)的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。其实就是通过双分派(就是通过多态两次才能决定具体使用哪个类),来对对象结构中元素进行操作,这些操作可以自由定义。



感悟

1.工厂:用来获取对象的,可以直接获得,也可以提供一点参数获取。

2.工厂:是用来解决客户端和逻辑代码之间的分离。工厂隐藏了容易变化的那部分,而让客户端看不出来。

3.方法:方法签名应该尽量简单(实际上是利用面向对象思想,传参有点过程编程的感觉)。对于可能用到的参数,可以通过设置在字段域中,不可避免的参数那就在方法签名中加上。

4.类不是越多越好。具有相同属性和功能的对象的抽象集合才是类。如打九折和打三折实际上是同一个类。

5.耦合度低体现:

        1).上层创建下层的类少,调用的类少

        2).对象通过接口来表示依赖关系

6.装饰模式特点:可以将核心职责和装饰功能分开,能给核心职责添加额外的一系列功能

7.代理模式用途:

1).远程代理,如rmi,webservice,隐藏对象实际在网络的其他地方,以致于在本地就可以直接使用

2).虚拟代理,其实就是用一个代理对象表示真实的实体,代理对象已加载完成,用户可以看到,但是真  实对象太大,慢慢加载,用户看不到,但并不影响使用。

3).安全代理,其实控制对象的访问权限

4).智能指引,就是为对象附加一些其他的功能

 

8.策略与代理比较:策略是关联一个对象,并不需要实现与这个对象一样的接口。代理也关联一个对象,同时需要实现与对象一样的接口

9.工厂方法模式:这个模式客服了简单工厂违背开发-封闭原则的缺点,尽管这样讲,但是还是得改变客户端的代码,而简单工厂不需要改变。(若是用反射客服端没必要改动,但简单工厂也可以用反射,所以两者用反射的话没法比较)

 

10.工厂方法模式适用的地方:需要多个相同对象进行操作,且会经常改变这些对象的类型,用工厂方法模式。说明:若有一个地方要多个相同对象进行操作,代码步骤为创建对象,调用对象方法。但是若改变这些对象为另一种类型,对于简单工厂来说,则需要修改客户端多条代码,但是工厂方法模式就需要改变一条代码:创建工厂的代码,修改工厂子类为合适的子类即可。

 

11.原型模式:其实这个模式就是克隆。一般在构造函数或初始化操作麻烦或者耗时长,但需要相同的对象,用这个模式较好。即影藏了对象创建的细节,又提升性能。

 

12.模板方法模式:这个模式一般用在当我们想要用一定的逻辑步骤完成一个事情时,但是其中有些步骤不能确定如何做,就可以使用这个模式。在超类中定义逻辑步骤的结构,子类去实现哪些可能不同的细节。优点是:通过把不变行为搬移到超类,去除了子类中的重复代码,体现代码服用。

 

13.外观模式:这个模式对于层与层之间的使用用得到。可以将某层的复杂性体现不到其它层,其它层还是可以很方便的使用某层的功能。如一个系统功能很好用,但是代码非常复杂,维护和扩展很麻烦。可以使用外观模式提供一个接口来使用此系统的能力,具体能力如何实现由实现类决定使用此系统哪些功能组合来实现这个能力。这样外面调用此系统的能力就是一个简单的接口,而看不出这个系统的复杂性。复杂性由一队伍维护,新功能新能力由另一队伍实现。

 

14.建造者模式:其实就是某些对象的构建一定是按照一定的步骤,但是每个步骤不同,就可以得到不同的对象,可以利用这个模式。如做饭(开火,放菜,放调料。。。),如画人物,如修路(得到水泥,铺设水泥,压平。。。,水泥,压的方式不同就可以得到不同的路)

 

15.观察者模式:就是当一个对象的改变,会影响其他对象,或需要让其他对象做出改变时使用这个模式。这个模式可以不知道有多少个观察者对象会因为主题对象的改变而改变。

 

16.抽象工厂:这个模式类似于工厂方法,不同点是这个模式在一个具体工厂类中可以创建多个产品,而工厂方法只创建一个。所以对于需要创建某个大前提下的一系列的产品可以用到这个模式。缺点是:增加需求时,修改的地方多,增加的地方也多,但相对于修改客户端好多了。

 

17.看法:大的分支判断会使得它们难以修改和扩展。

 

18.状态模式:解决的是根据状态不同,行为不同的条件判断表达式过于复杂时,就可以利用状态模式。由于每增加一个状态,就是定义一个新类,所以扩展很容易。注意的是:每个状态类的方法里要能根据状态不是自己所对应的状态时,可以改变工作上下文的状态类。

 

19.适配器模式:主要应用于希望复用一些现存的类(这些类能做相同的事或相似的事),但是接口又与复用环境不一致的情况。一般在双方都不太容易修改的时候再使用适配器模式适配,而不是一有不同且又要用某个类的功能就使用这个模式。所有说前期就要设计好,别出现这种接口不兼容的情况。

 

20.备忘录模式:将细节封装在了备忘录里,改变保存细节也不影响客户端。适用于当角色的状态改变的时候,有可能这个状态无效,就可以使用备忘录将状态恢复原状。

 

21.组合模式:组合模式使部分与整体可以统一的表示。使用场景是当需求中是体现部分与整体层次的结构,且希望用户可以忽略组合对象与单个对象的不同(继承或实现同一个类或接口),统一使用结构中的所有对象,就可以使用组合模式。这个模式的好处是程序不需要关心结构中的对象是叶节点还是树枝,直接使用(因为它们的功能是同一个方法名)。

 

22.迭代器模式:好处是分离出集合对象的遍历行为,抽象出一个迭代器类来负责。这样既可以做到不暴露内部结构,又可以让外部透明的访问内部数据。使用场景:需要访问一个集合对象所有数据,而不管这些对象是什么,就可以使用这个模式。

 

23.桥接模式:其实就是利用一个类合成/聚合了另一个类,这样这两个类都可以独立的变化而不相互影响。当一个系统可能从多个角度分类,每一种分类都可能变化,就可以利用这种模式将他们分离开来使它们独立的变化,减少耦合。

 

24.命令模式:利用中间类来消除请求者与服务者之间的紧耦合。好处:1.能容易的设计一个命令(请求)队列;2.可以容易的将命令记录日志;3.允许接收请求的一方可以拒绝请求;4.可以对请求撤销和重做;5.添加新的请求类满足开放——封闭原则。

 

25.职责链模式:当客户提交一个请求,请求会沿着职责链传递直至有一个具体的处理者处理。链中的对象需要保持一个后继的矗立着的引用,不需要保持所有,所以它本身不知道链的结构。我们可以随时的修改一个职责链的结构,从而提高了灵活性。

 

26.中介者模式:让对象的网状交互(多对多),变成星型交互(多对一),减少了对象之间的耦合。缺点是这个模式将复杂性从对象上转移到中介者上,所以当系统中出现了多对多的情况时,不要急着使用中介者模式,先反思是不是这个系统的设计不合理。

 

27.享元模式:其实就是共享一些对象,减少对象的创建。使用的地方:当一个程序使用了大量对象,而这些对象造成了很大的存储开销,同时这些对象可以共享一些内部状态,可以考虑使用这个模式。好处:减少系统资源的消耗。由于这个模式需要维护一个记录了已有共享对象的列表,所以会消耗资源和提高复杂性,所以在对象比较少的时候,尽管有可以共享的内部状态,也没必要考虑这个模式,除非对象足够多。

 

28.解释器模式:顾名思义就是解释器,可以理解类似于编程语言的解释器或编译器,只是没它们那么高级。当一个特定类型的问题发生频率高,没必要为这个类型问题创建一个很大的对象去响应解决。而是使用这个模式,创建一个简单的小表达式对象,并通过解释器去解释并执行相关操作来解决。这个模式不足是文法太多,就会导致文法类太多,以至于系统变得复杂。

 

29.访问者模式:这个模式的前提是数据结构的元素类型不能变化。好处是:将对应类型的元素与相应操作解耦,使操作可以独立的变化。所以说这个模式对于那些元素类型(可以理解为数据结构)不会变化,而对应于元素的操作容易变化的时候用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: