03 2011 档案
摘要:1. 动机采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行时代价——主要指内存需求方面的代价。如何在避免大量细粒度对象问题的同时,让外部客户程序仍然能够透明地使用面向对象的方式来进行操作?2. 意图运用共享技术有效地支持大量细粒度的对象。3. 结构图4. 几个要点• 面向对象很好地解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。• Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方
阅读全文
摘要:1. 动机上述A方案的问题在于组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合面临很多变化的挑战。如何简化外部客户程序和系统间的交互接口?如何将外部客户程序的演化和内部子系统的变化之间的依赖相互解耦?2. 意图为子系统中的一组接口提供一个一致的界面,Façade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。3. 结构图4. 几个要点• 从客户程序的角度来看, Facade模式不仅简化了整个组件系统的接口,同时对于组件内部与外部客户程序来说,从某种程度上也达到了一种“解耦”的效果——内部子系统的任何变化不会影响到Fa
阅读全文
摘要:前言 .net平台的开发人员肯定都知道委托,但是对于菜鸟级成员来说,对委托的深入了解却不是一件很容易的事情。比如我就长期处于迷惑的状态。后来逐渐看一些书及文章,才渐渐清晰一些了。发现其实委托也不是多高深的东西,前面的困惑应该是学习方法不当导致的结果(部分培训机构及劣质书籍)。下面是个人目前对委托的了解,不一定准确完善,只期抛砖引玉。相关概念 *函数指针:保存 函数首地址的 变量。 函数指针是一个变量,只不过其中保存的不是数据,而是一个地址值,是某一个函数的地址值。 *委托 .net平台的委托是一种特殊的函数指针,他使用对象(代替了变量)来保存函数地址,其中加入了函数签名机制,从而保证了类型的安
阅读全文
摘要:1. 动机上述描述的问题(用继承来扩展功能)根源在于我们“过度地使用了继承来扩展对象的功能”,由于继承为类型引入的静态特质(编译时就需要确定的东西),使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响将为最低?2. 意图动态地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活。3. 结构图4. 几个要点• 通过采用组合、而非继承的手法, Deco
阅读全文
摘要:1. 动机上述描述的问题根源在于:客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构(而非抽象接口)的变化将引起客户代码的频繁变化,带来了代码的维护性、扩展性等弊端。如何将“客户代码与复杂的对象容器结构”解耦?让对象容器自己来实现自身的复杂结构,从而使得客户代码就像处理简单对象一样来处理复杂的对象容器?2. 意图将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。3. 结构4. 几个要点•Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一 对多”的关系转化为“一对一”的关系,使得客户代码可以一
阅读全文
摘要:1. 动机思考上述问题的症结:事实上由于Tank类型的固有逻辑,使得Tank类型具有了两个变化的维度——一个变化的维度为“平台的变化”,一个变化的维度为“型号的变化”。如何应对这种“多维度的变化”?如何利用面向对象技术来使得Tank类型可以轻松地沿着“平台”和“型号”两个方向变化,而不引入额外的复杂度?2. 意图将抽象部分与实现部分分离,使它们都可以独立地变化。3. 结构4. 几个要点•Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有 的绑定关系,使得抽象(Tank的型号)和实现(不同的平台)可以沿着各自的维度来变化。• 所谓抽象和实现沿着各自纬度的变化,即“子类化”它们,比如
阅读全文
摘要:1. 动机在软件系统中,由于应用环境的变化, 常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。如何应对这种“迁移的变化”?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?2. 意图将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。3. 结构4. 几个要点• Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况” ,在遗留代码复用、类库迁移等方面非常有用。•GoF23 定义了两种Adapter模式的实现结构:对象适配器和类适配
阅读全文
摘要:1. 动机在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一致的接口。如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象” ,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?2. 意图使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。3. 结构4. 几个要点•Prototype模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求 这些“易变类”拥有“稳定的接口”。•Prototype模式对于“如何创建易变类的实体对象”采用“原型克隆”的
阅读全文
摘要:1. 动机在软件系统中,经常面临着“某个对象”的创建工作;由于需求的变化,这个对象经常面临着剧烈的变化,但是它却拥有比较稳定的接口。如何应对这种变化?如何提供一种“封装机制”来隔离出“这个易变对象”的变化,从而保持系统中“其他依赖该对象的对象”不随着需求改变而改变?2. 意图定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。3. 结构4. 几个要点• Factory Method模式主要用于隔离类对象的使用 者和具体类型之间的耦合关系。面对一个经常变 化的具体类型,紧耦合关系会导致软件的脆弱。• Factory Method模式通过
阅读全文
摘要:1. 动机在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?2. 意图将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。3. 结构4. 几个要点• Builder 模式主要用于“分步骤构建一个复杂的对 象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。• 变化点在哪里,封装
阅读全文
摘要:1. 动机在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?2. 意图提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。3. 结构4. 几个要点•“系列对象”指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中的“道路”与“房屋”的依赖,“道路”与“地道”的依赖。• Abstract Factory模式主要在于应对“新系列”的需求变动。 其缺点在于难以应对
阅读全文
摘要:概述:该讲主要描述了 面向对象设计模式的分类以及Singleton单件模式。一、面向对象设计模式的分类从目的来看:– 创建型(Creational)模式:负责对象创建。– 结构型(Structural)模式:处理类与对象间的组合。– 行为型(Behavioral)模式:类与对象交互中的职责分配。从范围来看:– 类模式 处理类与子类的静态关系。– 对象模式 处理对象间的动态关系。二、Singleton单件模式1. 动机在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?这应
阅读全文
摘要:该讲描述了面向对象与设计模式的基础思想以及两者之间的关系。下面是择取的个人认为比较有收获的观点:1. 对象是什么?– 从概念层面讲,对象是某种拥有责任的抽象。– 从规格层面讲,对象是一系列可以被其他对象使用– 从语言实现层面来看,对象封装了代码和数据。2.• 针对接口编程,而不是针对实现编程– 客户无需知道所使用对象的特定类型,只需要知道对象拥有客户所期望 的接口。• 优先使用对象组合,而不是类继承– 类继承通常为“白箱复用”,对象组合通常为“黑箱复用”。继承在某种程度上破坏了封装性,子类父类耦合度高;而对象组合则只要求被组合的对 象具有良好定义的接口,耦合度低。• 封装变化点– 使用封装来创
阅读全文

浙公网安备 33010602011771号