大话设计模式--笔记

1、简单工厂模式

        

2、策略模式

         面向对象的编程,并不是类越多越好,类的划分就是为了封装,但是分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。

         策略模式(Strategy)他定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化不会影响到使用算法的用户。

         策略模式是一种定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是实现不同,他可以用相同的方法调用所有的算法,减少了各种算法类与使用算法类之间的耦合。

         策略模式简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。

         当不同的行为堆砌在一个类中,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的类中,可以再使用这些行为的类汇总消除条件语句。

         基本的策略模式中就是用来封装算法的,但是在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在更新过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化。

3、单一职责原则

         就一个类而言,应该仅有一个引起她变化的原因。

         如果一个类承担的职责过多,就等于把这些职责耦合在一起。一个职责的变化可能会消弱或者抑制这个类完成其他职责的能力。

         软件设计真正要做的许多内容,就是发现职责并把那些职责互相分离。如果你能想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责。

4、开放——封闭原则

开放--封闭原则,即:软件实体(类、模块、函数等)应该可以扩展,但是不能修改。即,对于扩展是开放的,对于修改是封闭的。

原因:在做任何系统的时候,系统的需求都不是一开始就确定的,在需求发生变化时,软件可以容易修改。设计人员必须对他设计的模块应该对哪种变化封闭做出选择。他必须猜测出最后可能发生变化的种类,然后构造抽象隔离那些变化。在最初编写代码时,假设变化不发生,等到发生变化时,就创建抽象来隔离以后发生的同类变化。

面对需求,对程序的改动是通过增加新的代码来进行的,而不是通过更改现有的代码。这就是开放封闭原则的精神。(更改现有代码可能会引起类中其他方法的更改,而增加代码不会引起其他变化)

开放--封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,可维护性、可扩展、可复用、灵活性好。开发人员应该对程序中出现的频繁变化的部分做出抽象。

5、依赖倒置原则

抽象不应该依赖于细节,细节应该依赖于抽象。通俗的讲,就是要针对接口编程,不要针对实现编程

依赖倒置原则:A:高层模块不应该依赖于底层模块,两都应该依赖于抽象。

B:抽象不应该依赖于细节,细节应该依赖于抽象。

里氏替换原则:子类必须能够替换掉他们的父类型。

一个软件实体如果使用的是父类,那么一定适用于子类,而且察觉不出父类对象和子类对象的区别。即如果把父类替换成子类,程序的行为没有变化。

依赖倒置原则是面向对象的标志。用哪种语言来编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象设计,反之就是面向过程设计。

6、装饰模式(Decorator)----主要功能就是动态添加额外的功能

        动态的给一个对象添加一些额外的职责或者行为。比生成子类更加灵活。

        装饰器模式提供了改变子类的灵活方案。装饰器模式在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。他是通过创建一个包装对象,也就是装饰来包裹真实的对象。

        当用于一组子类时,装饰器模式更加有用。如果你拥有一族子类(从同一个父类派生而来),你想要在与子类独立使用的情况下添加额外的特性,就可以只用装饰器模式,避免代码重复和具体子类数量的增加。

7、代理模式(proxy)

代理模式:为其他对象提供一种代理以控制对这个对象的访问。

类型:1.远程代理。为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。

例如:在应用程序中加入一个web引用,引用一个webservice,则会在项目中生成一个webservice的文件夹和一些文件,这就是代理。客户端程序调用代理就有可以解决远程访问问题。

2.虚拟代理。根据需要创建很大很大的对象,通过他来存放实例化需要很长时间的真实对象

例如:打开HTML网页时,先显示文字后显示图像。先显示所有文字在一张一张显示图像。那希望未打开的图片框就是通过虚拟代理替代了真实的图像。

3.安全代理。用来控制真实对象访问时的权限。一般用于不同对象应该有不同的访问权限的时候。

4.智能引用。指当调用真实的对象时,代理处理另外一些事。

代理模式就是在访问对象时引入一定程度的间接性。真是因为这种间接性,可以附加多种用途。

8、工厂方法模式(FactoryMethod)

工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法 使得一个类的实例化延迟到子类。

简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。

9、原型模式(prototype)

用原型实例制定创建对象的种类,并且通过拷贝这些原型对象创建新的对象。

原型模式其实就是从一个对象再创建另一个可定制对象,而且不需要知道任何创建的细节。

不重新初始化对象,而是动态获取对象运行时的状态。原始对象机器复本引用同一个对象。

浅复制:被复制的对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。

深复制:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

10、模板方法模式(TemplateMethod)

当我们要完成某一细节层次一致的一个过程或者一系列步骤,但是个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。

模板方法模式:定义一个操作中的的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的数据结构即可重新定义该算法的某些特定步骤。

将子类变量的声明改成父类,这样就可以利用多态性,实现代码复用。

模板方法模式是通过把不变的行为搬到父类中,去除子类中的重复代码,它提供了一个很好的代码复用平台

11、迪米特法则(LoD)

如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法,可以通过第三者转发这个调用。

迪米特法则首先强调的是在类的结构设计上,每一个类都应当尽量降低成员的访问权限。迪米特法则的根本思想是强调了类之间的耦合程度。

12、外观模式(Facade)------常用的模式之一

为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

如何使用外观模式?

首先,在设计初期阶段,应该要有意识的将不同的两个层分离。在层与层之间建立外观模式。其次,在开发阶段子系统往往因为不断的重构演化而变得原来越复杂。增加外观模式可以提供一个简单的接口,减少他们之间的依赖。第三,在维护一个遗留的大型系统时,可能这个系统已经非常难以维护和扩展了。为新系统开发一个外观Facade类,来提供设计粗糙或者高度复杂的遗留代码的比较清晰简单接口,让新系统与Facade对象进行交互,Facade与遗留代码交互所有复杂的工作。

13、建造者模式(Builder)(待补充)

如果需要将一个复杂对象的构建和他的表示分离,使得同样的构建过程可以创建不同的表示意图时,需要使用构建者模式。(又叫生成器模式)。

14、观察者模式

定义了一种一对多的关系,让多个观察者对象同时监听某一个主题。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

将一个系统分割成一系列相互协作的类有一个很不好的副作用,就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用带来不变性。

什么时候需要使用观察者模式?

当一个对象的改变需要同时改变其他对象时,而且他不知道有多少对象需要改变时,应该考虑使用观察者模式。

当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,这时用观察者模式可以将这两个封装在独立的对象中使得他们各自独立地变化不会影响另一边的变化。

总的说来,观察者模式所做的工作就是在解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化不会影响另一边的变化。

15、抽象工厂模式(AbstractFactory)

提供一个创建一系列相关或相互依赖的对象的接口,而无需指定他们具体的类。

需要创建抽象工厂类,也需要创建具体的工厂类,需要创建抽象产品类,也需要创建具体产品类。

抽象工厂接口,应该包含所有的产品创建的抽象方法。

在运行时刻创建抽象工厂的实现——具体工厂的实例,

抽象工厂模式的优点与缺点:

易于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,这就使得改变换一个应用的具体工厂变得非常容易。他只需要改变具体工厂即可使用不同的产品配置。二、他让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,他不会出现在客户端代码中。

16、状态模式

状态模式主要解决的是的那个控制一个对象装填转换的条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

当以对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

状态模式的好处:将特定状态相关的的行为局部化,并且将不同状态的行为分割开来。即将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个类中,所以通过定义新的子类可以很容易的增加新的状态和转换。

使用状态的目的是为了消除庞大的条件分支语句,大的分支语句会使得他们难以修改和扩展。状态模式通过吧各种状态转移逻辑分不到子类中,减少相互间的依赖。

当一个对象的行为取决于他的状态并且必须在运行时根据状态改变他的行为时,考虑使用状态模式。

17、适配器模式(Adapter)

将一个类的接口转换成客户需要的接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

系统的数据和行为都正确,但是接口不符合时候,考虑使用适配器,目的是是控制范围职位的一个原有对象与某个接口匹配。适配器模式主要应用与希望复用一些现存的类,但是与复用环境要求不一致的情况。比如在需要对早期代码复用一些功能等应用上很有价值。

适配器模式分为类适配器模式和对象适配器模式。类适配器模式是适用于通过多继承多于一个接口和另一个接口进行匹配,由于多数面向对象语言不支持多继承。。。

对象适配器模式:

使用一个已经存在的类,但那时如果他的接口及方法和你的要求不相同时,考虑使用适配器模式。

18、备忘录模式(Memonto)

         在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存状态。

         备忘录模式适用于功能比较复杂,但是需要维护或者记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分,可以将信息还原到前一状态。

         如果在某个系统中使用命令模式,需要实现命令已给的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。

19、组合模式(Composite)

         将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

         组合模式定义了包含基本对象和组合对象的类层次结构。基本对象可以被组合对象组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归,任何用到基本对象的地方都可以使用组合对象。

20、迭代器模式

         提供一种方法顺序访问一个聚合对象中各元素,而又不暴露该对象内部表示。

         当需要访问一个聚集对象,而且不管这些对象是什么都需要遍历的时候,就应该考虑使用迭代器模式。

         当需要对聚集对象有多种方式遍历时,可以考虑使用迭代器模式。

21、单例模式(Singleton)

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

         让类自身负责保存他的唯一实例。这个类可以保证没有其他实例可以被创建,并且他可以提供一个访问该实例的方法。

        

22、桥接模式(Bridge)

         合成/聚合复用原则(CARP)

         尽量使用合成/聚合,尽量不要使用类继承。

         合成(composition),聚合(aggregation)都是关联的特殊种类。合成则是一种强的”拥有“关系,体现了严格的部分与整体的关系,生命周期是一样的;聚合表示一种弱的“拥有"关系,体现的是A对象可以包含B对象,但是B对象不是A对象的一部分。

         优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上。这样类和类的继承层次会保持较小规模,并且不太可能增长成为不可控制的庞然大物。

         继承是一种强耦合的结构。

         桥接模式:将抽象部分与他的实现部分分离,使得他们都可以独立地变化。

         抽象与实现分离并不是说让抽象类与派生类分离,因为这没有任何意义。实现指的是抽象类和他的派生类用来实现自己的对象。

         由于实现的方式有多种,桥接模式的核心意图是把这些实现独立出来,让他们各自独立的变化,这就使得每种实现的变化不会影响其他实现,从而达到应对变化的目的。

         实现系统可能有多种角度的分类,每一种分了都有可能变化,那么就把这种多角度分离出来,让他们独立变化,减少他们之间的耦合。

23、命令模式

         将一个请求封装为一个对象,从而使得你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销操作。

        

         敏捷开发原则告诉我们,不要为代码添加基于猜测的、实际不需要的功能。如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要的时候把原来的代码重构为命令模式才有意义。

 

24、职责链模式(Chainof Responsibility)

         使多个对象都有机会处理请求,从而避免请求的发送者和接受者时间的耦合关系。将这个对象连城一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

         接收者和发送者都没有对方的 明确信息,且链中的对象自己也不知道链的结构,结果是职责链可简化对象的相互连接,他们仅需保持一个指向其后继者的引用,而不需保持他所有的选择接收者的引用。大大降低了耦合度。

25、中介者模式(Mediator)

         尽管将一个系统分割成许多对象通常可以增加其可复用性,但是对象间的相互关联的激增又会降低其可复用性。

         大量的连接使得一个对象不可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,所以,对系统的行为进行任何较大的改动就十分困难。

         中介者模式:用一个中介对象来封装一系列的对象交互。中介者使得各对象不需要显示的相互引用,从而使得耦合松散,而且可以独立的改变他们之间的交互。

         中介者模式很容易在系统中使用,也很容易在系统中误用。当系统中出现了”多对多“交互复杂的对象群时,不要急于使用中介者模式,而要反思你的系统设计上是不是合理。

         中介者模式一般用于一组以定义良好但是复杂的方式进行通信的场合,以及向定制一个分布在多个类中的行为,而又不想生成太多子类的场合。

26、享元模式(Flyweight)

         享元模式,运用共享技术有效的支持大量细粒度的对象。

         如果一个程序使用了大量的对象,而这些大量的对象造成的很大的存储开销是就应该考虑使用享元模式。还有就是对象的大多数状态可以使外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。

27、解释器模式(interpreter)

         如果一个特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决问题。

28、访问者模式(Visitor)

         表示一个作用于某对象结构中的各元素的操作,他是你可以在不改变各元素的类的前提下定义作用于这些元素而的操作。

         访问者模式适用于数据结构相对稳定的系统,他把数据结构和作用于数据结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。

         访问者模式的目的是要把处理从数据结构中分离出来。有比较稳定的数据结构,又有益于变化的算法的话,使用访问者模式就比较合适。

         访问者模式的优点是增加新的操作很容易,因为增加新的操作意味着增加一个新的访问者。访问者模式将一个行为集中到一个访问者对象中。

         访问者模式的缺点是使增加新的数据结构变得困难了。

        

        

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值