大话设计模式这本书写的非常有创意,非常适合我这种新手。用了大约两个星期的时间看完了这本书,代码全部都敲了一遍,虽然没有一点基础,但是还是领略到了面向对象的威力。看完之后再也不想使用面向过程的语言了,比如VB,想当初我也是VB狂热者,但是现在我几乎不想再使用了。现在只想着写点什么用上它几种设计模式。
可能是第一次接触这些东西,有些感觉看懂了,但是很难应用到实际编程中;有些感觉没看懂,但是还能说出那么点东西来。听七期学长说他们当初看了两遍,要求能背着写出代码,不知道这次我们八期要求怎么这么低,我只看了一遍,但是看的非常仔细。我深深的知道,设计模式仅仅靠看一本是无法理解的,何况是一本入门级的书?我即听从米老师的教诲:不要在没必要细节上浪费时间;又综合了自己的看法:有些东西还是弄明白点比较好。结果就这么着把这本书看完了,感觉没记住多少东西,现在冒然写总结其实我总结不出什么来,现在的一切都很模糊;但是如果没有总结,这本书就白看了,所以我把每一个模式的定义和简单理解罗列一下。这些只是我作为一个初学者的理解,难免非常浅显,而且很可能有错误,见谅!
1. 简单工厂模式:定义:用一个单独的类完成创建对象的过程,即工厂类。理解:生产对象的工厂,由参数生成相应的对象,容易扩展,扩展的同时不需要也不影响现有功能。
2. 策略模式:定义:它定义了算法家族,分别封装起来,让它们直接可以互相替换,此模式让算法的比啊好,不会影响到使用算法的客户。理解:可以理解为“受保护的简单工厂模式”,把简单工厂模式封装起来,通过协调类调用工厂,对客户端完全屏蔽工厂。
3. 单一职责原则:定义:就一个类而言,应该仅有一个引起它变化的原因。理解:类的职责单一化,减少类的负担。
4. 开放-封闭原则:定义:软件实体(类、模块、函数等等)应该可以扩展,但是不可更改。理解:对修改封闭,对扩展开放。解决方法是抽象,用抽象是隔离变化。
5. 依赖倒转原则:定义:高层模块不应该依赖于底层模块,两个都应该依赖于抽象。抽象不应该依赖细节,细节应该依赖抽象。理解:依赖倒转原则是“封闭-开放”原则实现的方针、指导思想。
6. 里氏代换原则:定义:子类型必须能够替换掉他们的父类型。理解:以抽象类或接口为父类,在使用时,以父类类型的“对象变量”作为参数,这样就可以接受任何一个继承抽象类或者实现接口的类的子类(的实例),相当于子类代换了父类,利用多态,可以完美实现“修改封闭,扩展开放”。
7. 装饰模式:定义:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。理解:把人和服饰分离,即高层模块不应该依赖底层模块,通过服饰抽象类(接口),很好的进行了分离,人使用接口,扩展时实现接口,体现了依赖于抽象的原则。
8. 代理模式:定义:为其他对象提供一种代理以控制对这个对象的访问。理解:无,非常简单。
9. 工厂方法模式:定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。理解:把工厂看成一个接口,让工厂的每个创建对象的功能去实现这个接口,去创建不同的对象,通过抽象,分解了工厂,从而封闭了修改,添加工厂新成员只需添加实现接口的类即可。但是这样无形的把判断创建哪个对象的压力(职责)放在了客户端,使客户端变得复杂,不是很好的办法。
10. 原型模式:定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。理解:原型模式就是实现ICloneable接口,实现这个接口唯一的Clone方法克隆自己。需要重点理解MenberwiseClone方法。理解后可知:浅复制就是克隆本身,完全遵从MenberwiseClone方法的规则(克隆新对象,字段复制,引用只复制引用),即外层对象克隆,内层对象引用。而深复制是增加了处理手段,让内层类实现ICloneable接口,在外层类创建对象(new)时,内层类克隆自己,实现内层类的分离。
11. 模版方法模式:定义:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模版方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。理解:当子类中重复与不重复的代码混杂时,把重复的代码搬到父类,不重复的(特有的)用虚方法或抽象方法延迟到子类中实现。在父类中定义一个整体的骨架方法,通过这个方法把父类的实现和子类的实现整合在一起完成功能。
12. 迪米特法则:定义:如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。理解:减少无关类直接的耦合,方便修改。
13. 外观模式:定义:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。理解:把一系列具有一定联系的子系统功能整合到外观类的一个方法中,复杂的交互都由外观类完成,客户端只需要调用外观类的方法即可。外观类就像一个形象良好的接口,供客户端简洁的调用。
14. 建造者模式:定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。理解:把一系列稳定的、普遍的、复杂的装配过程放在指挥类中完成,定义抽象父类,用多态去创建不同的子类(产品),用户只需要调用指挥类并指定产品即可。把复杂的装配隔离到指挥类。
15. 观察者模式:定义:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象(通知者)。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。理解:当一个对象变动时要通知其他不定个数的对象。变动的类相当于通知者,被通知的类相当于观察者。可以用集合实现,双方都依赖于抽象(通知者有抽象通知者,观察者有抽象观察者,这样会很容易扩展)。也可以用委托,大大减少耦合(观察者必须指定通知者,也就是让谁通知)。
16. 抽象工厂模式:定义:提供一个创建一系列相关或者相互依赖对象的接口,而无需指定他们具体的类。理解:简单工厂模式----工厂方法模式(抽象工厂来分离工厂功能)----抽象工厂模式(细化抽象,把每一个分开的小工厂继续细化,再分成不同的方法(接口方法),创建该工厂的又一个分支,实现当前工厂下的多功能。)。反射理解:反射就是可以动态的创建不同类的实例,把创建实例从编译时改成运行时。可以在工厂模式中替换switch、if等分支语句。反射要求以字符串的形式传入要实例化的类,所以可以用变量代替,大大的增加了灵活性。
17. 状态模式:定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。理解:当程序运行时需要不断地判断某一条件(状态),然后根据条件去执行不同的动作,就可以考虑用状态模式。状态模式可以消除庞大的分支判断,把不同状态的转移逻辑和每个状态的动作转移到抽象状态类的子类。让每个子类决定下一个状态(每个子类都进行判断,满足则执行自己功能,不满足则转向下一个类,直到得到处理或者链结束。每个子类只需要知道下一个类是哪个即可,无需知道整个链式结构)。
18. 适配器模式:定义:将一个类的接口转换成客户希望的另外一个接口。此模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。理解:通过一个翻译类(适配器类)把一个类的接口转化为另一种形式,通过调用这个翻译类的期望接口来间接调用另一个类。
19. 备忘录模式:定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。理解:备忘录模式把数据保存在箱子类中(体现了数据保存在对象外),然后通过备忘录管理类去访问箱子。在主类保存时,新建一个箱子类实例,保存数据,并把该箱子的实例交给管理类托管,恢复时调用管理类托管的箱子即可。
20. 组合模式:定义:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。理解:核心思想就是树枝类和树叶类。树枝可以分支(遍历),而树叶不可以。可以把树叶理解为“功能终端”,具体功能实现者,而树枝就是可以遍历其包含枝、叶的分支者。树枝或树叶隶属于哪个树枝就加入那个树枝的集合,通过递归即可达到效果。
21. 迭代器模式:定义:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。理解:无,较简单。
22. 单例模式:定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。理解:保证一个类只有一个实例,这个责任要放到这个类,而不应该让别的类决定。方法是把类的构造方法改成私有,确保外界无法通过new实例化,然后提供一个公有的静态的方法去创建实例。把保护实例的责任放在这个方法中(虽然构造方法私有,但是类内部还是可以访问的。创建成功后用这个公共静态方法返回,供调用者使用。这样做的好处是客户端只需要使用该类即可,至于是否实例化、如何实例化由类自己负责,减轻了客户端的压力,减少耦合。)。
23. 桥接模式:定义:将抽象部分与它的实现部分分离,使他们都可以独立的变化。理解:把混杂在一起的抽象分离出来,让它们单独实现。然后通过合成/聚合重新整合在一起。这样可以减少类之间的耦合,使结构松散,避免庞大的继承体系,增强复用性。体现在代码中就是把复杂的继承关系化为“方法-参数”,“部分”对象作为“整体”的方法的参数,通过参数聚合在一起(刚才讲到的是聚合,个人认为合成应该不是靠参数,应该是一种“你中有我,我中有你”的强耦合结构)。
24. 命令模式:定义:将一个请求封装为一个对象,从而使你可用不同的请问对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。理解:通过服务员类对请求者和执行者进行解耦合。
25. 职责链模式:定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。理解:把具有一定职责(处理能力)的类抽象成一个抽象父类,父类中包括了设置上级的方法和抽象处理方法。在客户端设计好上级关系,然后调用最低以及的对象处理事务,当该类无法处理时,会自动调用它的上一级的处理方法,直到可以处理为止。好处是通过设置上级把职责对象串在一起,每个部分知道上级是谁即可,无需了解整个链的结构,而且请求者只需调用最底层的职责对象即可,最终被哪个对象处理请求者不知道也无需知道。一切都是自动进行的。
26. 中介者模式:定义:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。理解:中介者承担了一切复杂通信,在关注对象中要指定中介类,在中介类中要包含所有的关注对象。通过关注对象的方法去调用中介者的协调方法,客户端不直接与中介类交互。
27. 享元模式:定义:运用共享技术有效地支持大量细粒度的对象。理解:通过usingsystem.Collections 引用Hashtable类来管理对象。给每个类一个标识(key),通过key来判断对象是否存在,存在直接按key返回,不存在则创建,然后通过Add方法加入Hasthtable类对象中,注意必须指定key。
28. 解释器模式:定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。理解:解释器模式就是用“迷你语言”来表现程序要解决的问题,以迷你语言写成“迷你程序”来表现具体的问题。
29. 访问者模式:定义:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。理解:能力有限,暂未理解该模式。
以上就是我对设计模式的理解了,通过学习设计模式,我觉得一个模式有没有看懂,比较好的判断标准就是会不会写客户端,如果一个模式看完之后不能独立写出客户端调用代码,说明根本没看懂。在学习设计模式的初级阶段,要试着刻意去使用设计模式,相信随着学习加深,做到“手中无剑,心中也无剑”的最高境界。