zoukankan      html  css  js  c++  java
  • 模式设计随学随机

    1.什么是设计模式?

    设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、带码设计经验的总结。

    2.应用设计模式有什么好处?

    设计模式是优秀的使用案例,使用设计模式可提高代码的重用性、让代码更容易被他人理解、保证代码可靠性。

     3.代理模式:

    (1)代理模式的核心作用---控制对象访问

    (2)代理模式将实现与代理分离,考虑到了单一指责原则

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

    10.几种代理模式:

    (1)虚拟代理:根据需要将资源消耗很大的对象进行延迟,正真需要的时候进行创建

    (2)智能代理:提供对目标对象额外服务

    (3)远程代理:为不同地理的对象提供局域网代表的对象

    (4)保护代理:控制用户的访问权限。

    11.代理模式实现---静态代理

    静态代理:代理和被代理对象在代理之前是确定的。他们都实现相同的接口或者继承相同的抽象类。

    12.代理模式---动态代理

    Java 动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:

    (1)Interface InvocationHandler:该接口中仅定义了一个方法

    public object invoke(Object obj,Method method,Object[] args)在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现。

    (2)Proxy:该类即为动态代理类

    static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h):返回代理类的一个实例,返回后的代理类可以当做被代理类使用(可使用被代理类的在接口中声明过的方法)

    13.动态代理的实现步骤:

    (1).创建一个实现接口InvocationHandler的类,它必须实现invoke方法

    (2)创建被代理的类以及接口

    (3)调用Proxy的静态方法,创建一个代理类

    newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

    (4)通过代理调用方法

    14.JDK动态代理与CGLIB动态代理区别:

    JDK动态代理:

    (1)只能代理实现了接口的类

    (2)没有实现接口的类不能实现JDK的动态代理

    CGLIB动态代理

    (1)针对类来实现代理的

    (2)对指定目标类产生 一个子类,通过方法拦截技术拦截所有父类方法的调用。

    15.单例模式(Singleton)<创建型模式>:

    (1)动机:在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?这应该是类设计者的责任,而不是使用者的责任。

    (2)意图:保证一个类仅有一个实例,并提供一个该实例的全局访问点。

    (3)单线程Singleton模式的几个要点

    (I)Singleton模式中的实例构造器可以设置为protected以允许子类派生。

    (II)Singleton模式一般不要支持ICloneable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。

    (III)Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样与Singleton模式的初衷违背。

    (IV)Singleton模式只考虑到了对象创建的管理,没有考虑对象销毁的管理。就支持垃圾回收的平台和对象的开销来讲,我们一般没有必要对其销毁进行特殊的管理。

    (V)不能应对多线程环境:在多线程环境下,使用Singleton模式仍然有可能得到Singleton类的多个实例对象。

    (4)将构造函数设置为private,只能内部调用,用一个静态字段累存储对象,可见,无论单例是 类型还是对象,都需要通过“静态”来实现。

    (5)其实,在系统中有许多种单例的情况等等

    (I)单例对象(如果单例是一个对象)

    (II)静态类(如果单例是一个方法)

    (III)全局变量(如果单例是一个变量)

    (IV)文档(如果单例是一个文档)

    (6)单例模式多线程的情况,如果有多线程,需要在单例上加”锁“。

    16.工厂模式<创建型模式>

    (1)变化点在“对象创建”,因此就“对象创建”

    (2)面向接口编程---依赖接口,而非依赖实现。

    (3)意图:提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需制定它们具体的类。

    (4)工厂模式的意图:定义一个接口来创建对象,但是让子类来决定哪些类需要被实例化。工厂方法把实例化的工作推迟到子类中去实现。

    (5)什么情况下适合工厂模式?

    (I)有一组类似的对象需要创建。

    (II)在编码时不能预见需要创建哪种类的实例。

    (II)系统需要考虑扩展性,不应依赖于产品类实例如何被创建、组合和表达的细节。

    (6)JDBC是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口。spring beanfactory: BeanFactory,作为Spring基础的IoC容器,是Spring的一个Bean工厂。如果单从工厂模式的角度思考,它就是用来“生产Bean”,然后提供给客户端。

    (7)工厂方法模式和抽象工厂模式对比

    (I)工厂模式是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的推广

    (II)工厂模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构。

    (III)工厂模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。

    (8)工厂模式的实现帮助我们

    (1)系统可以在不修复具体工厂角色的情况下引进新的产品

    (2)客户端不必关心对象如果创建,明确了职责

    (3)更好的理解面向对象的原则 、面向接口编程,而不要面向实现编程。

    (9)所谓工厂,就是封装一个对象创建过程,对于一种抽象,到底由哪个具体实现,由工厂决定。

    (10)工厂模式的分类:工厂方法模式、抽象工厂模式都是在简单工厂模式这个基础上再去抽象、分离,而来的。

    (I)简单工厂:只是将对象创建过程简单封装。

    (II)工厂方法:在简单工厂的基础上,将创建过程抽象、派生出子类,由具体的子类创建对象,适合创建一个组合对象;

    (III)抽象工厂:在工厂方法的基础上,每个子类都被赋予了多个对象的创建功能,适合创建一个家族对象。

    三者应对的情况,是越来越复杂的,不同情况采用不同的工厂。

    (11)Factory Method工厂方法。

    (I)从耦合关系谈起:耦合关系直接决定着软件面对变化时的行为。模块与模块之间的紧耦合是得软件面对变化时,相关的模块都要随之更改。模块与模块之间的松耦合使得软件面对变化时,一些模块更容易被替换或者更改,但其他模块保持不变。

    (II)动机:在软件系统中,经常面临着“某个对象”的创建工作;由于需求的变化,这个对象经常面临着剧烈的变化,但是它却拥有比较稳定的接口。

    (III)意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。

    (IV)Factory Method模式主要用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系会导致软件的脆弱。

    (V)Factory Method模式通过面向对象的手法,将所要创建的对象工作延迟到子类,从而实现一种扩展的策略,较好的解决了这种紧耦合关系。

    (VI)区别:抽象工厂模式:是解决“系列对象”的需求变化。工厂方法模式:是决绝“当个对象”的需求变化。

    (VII)Factory Method模式主要用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系会导致团建的脆弱。Factory Method模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。Factory Method模式解决“单个对象”的需求变化,Abstract Factory模式解决“系列对象”的需求变化,Builder模式解决“对象部分”的需求变化。

    17.Builder生成器模式、创建者模式<创建型模式>

    (1)意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

    (2)Builder模式是一种对象创建型模式之一,用来隐藏符合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象。

    (3)建造模式的结构:

    (4)创建者模式应用场景
    (I)对象的创建:Builder模式是为对象的创建而设计的模式

    (II)创建的是一个复合对象:被创建的对象为一个具有复合属性的复合对象。

    (III)关注对象创建的各部分的创建过程:不同的工厂(这里指builder生成器)对产品属性有不同的创建方法。

    (5)创建者模式适用于创建有不同配置、不同工艺的复杂对象,该模式巧妙的将对象创建过程中的“不同配置”隔离,将“不同顺序”也隔离。充分解耦。

    19.Prototype原型模式

    (1)抽象不应该依赖于实现细节,实现细节应该依赖于抽象。

    (2)动机:在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。

    (3)意图:使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。

    (4)Prototype模式同样用于隔离类对象的使用者和具体类型(异变类)之间的耦合关系,它同样要求这些“异变类”拥有“稳定的接口”。

    (5)Prototype模式对于“如何创建异变类的实体对象”采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象---所需工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方不断地Clone。

    (6)Prototype模式中的Clone方法可以利用.Net中的Object类的MemberwiseClone()方法或者序列化来拷贝深拷贝。

    (7)Prototype模式是一种对象创建模式,它采取复制原型对象的方法来创建对象的实例。使用Prototype模式创建的实例,具有与原型一样的数据。

    (8)原型模式的特点:

    (I)由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象自身。

    (II)目标对象对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。

    (III)根据对象克隆深度层次的不同,有浅度克隆与深度克隆。

    (9)原型模式应用场景:

    (I)在创建对象的时候,我们不只是希望被创建的对象继承其基类的基本结构,还希望继承原型对象的数据。

    (II)希望对目标对象的修改不影响既有的原型对象(深度克隆的时候可以完全不影响)。

    (III)隐藏克隆操作的细节。很多时候,对对象本身的克隆需要涉及到类本身的数据细节。

    20.有关创建性模式的讨论

    (1)Singleton模式解决的是实体对象个数的问题。除了Singleton之外,其他创建型模式解决的都是new所带来的耦合关系。

    (2)Factory Method,Abstract Factory,Builder都需要一个额外的工厂类来负责实例化“异变对象”,而Prototype则是通过原型(一个特殊的工厂类)来克隆“异变对象”。

    (3)如果遇到“异变类”,期初的设计通常从Factory Method开始,当遇到更多的复杂变化时,在考虑重构为其他三种工厂模式(Abstract Factory,Builder,Prototype)。

    21.Adapter模式(适配器模式)

    (1)适配,即在不改变原有实现的基础上,将原先不兼容的接口转换为兼容的接口。

    (2)动机:在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。

    (3)意图:将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

    (4)Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。

    (5)GoF23定义了两种Adapter模式的实现结构:对象适配器和类适配器。但类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。

    (6)Adapter模式可以实现的非常灵活,不必拘泥于Gof23中定义的两种结构。例如,完全可以将Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。

    (7)Adapter模式本身要求我们尽可能地使用“面向接口的编程”风格,这样才能在后期很方便地适配。

    (8).NET框架中的Adapter应用

    (I)在.NET中复用COM对象:

    (i)COM对象不符合.NET对象的接口

    (ii)使用tlbimp.exe来创建一个Runtime Callable Wrapper(RCW)以使其符合.NET对象的接口。

    (II).NET数据访问类(Adapter变体):

    (i)各种数据库并没有提供DataSet接口

    (ii)使用DbDataAdapter可以将任何各数据库访问/存取适配到一个DataSet对象上。

    (III)集合类中对现有对象的排序(Adapter变体):

    (i)现有对象未实现IComparable接口

    (ii)实现一个排序适配器(继承IComparer接口),然后再其Compare方法中对两个对象进行比较。

    (9)Adapter是构造模式之一,通过Adapter模式可以改变已有类(或外部类)的接口形式。

    (10)适配器模式应用场景

    Adapter模式通过定义一个新的接口(对要实现的功能加以抽象),和一个实现该接口的Adapter(适配器)类来透明地调用外部组件。这样替换外部组件时,最多只要修改几个Adapter类就可以了,其他源代码都不会受到影响。

    (11)适配器模式的结构------通过继承实现Adapter

    (12)适配器模式的结构-----通过委让实现Adapter

    22.Bridge桥接模式

    (1)意图:将抽象部分与实现部分分离,使它们都可以独立地变化。

    (2)Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。

    (3)所谓抽象和实现沿着各自维度的变化,即“子类化”它们,(比如不同的TanK型号子类,和不同的的平台子类)。得到各个子类之后,便可以任意组合它们,从而获得不同平台上的不同型号。

    (4)Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方案。

    (5)Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈---换言之两个变化不会导致纵横交错的结构,并不一定要使用Bridge模式。

    (6)Bridge模式是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展。

    (7)桥接模式的结构:

    (8)桥接模式的角色和职责

    (I)Client:Bridge模式的使用者

    (II)Abstraction:抽象类接口(接口或抽象类)、维护对行为实现(Implementor)的引用

    (III)Refined Abstraction:Abstraction子类

    (IV)Implementor:行为实现类接口(Abstraction接口定义了基于Implementor接口的更高层次的操作)

    (V)ConcreteImplementor:Implementor子类

    23.Composite组合模式

    (1)动机:客户代码过多地依赖于对象容器复杂的内部实现结构,对象容器内部实现结构(而非抽象接口)的变化将引起客户代码的频繁变化,带来了代码的维护性、扩展性等弊端。

    (2)意图:将对象组合成树形结构以表示“部分-整数”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。

    (3)Composite模式采用树形结构来实现普通存在的对象容器,从而将“一对多”的关系转化为“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,无需关系处理的是单个的对象,还是组合的对象容器。

    (4)将“客户代码与复杂的对象容器结构”解耦是Composite模式的核心思想,解耦之后,客户代码将于纯碎的抽象接口----而非对象容器的复内部实现结构---发生依赖关系,从而更能“应对变化”。

    (5)Composite模式中,是将“Add和Remove等和对象容器相关的方法”定义在“表示对象容器的Composite类”中,是一个关乎“透明性”和“安全性”的两难问题,需要仔细权衡。这里有可能违背面向对象的“单一职责原则”,但是对于这种特殊权衡,这又是必须付出的代价。ASP.NET控件的实现在这方面为我们提供了一个很好的示范。

    (6)Composite模式在具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率。

    (7)Composite模式也叫组合模式,是构造型的设计模式之一。通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。

    (8)组合模式的结构:

    (9)组合模式的角色和职责

    (I)Component(树形结构的结点抽象):(i)为所有的对象定义统一的接口(公共属性、行为等的定义)(ii)提供管理子节点对象的接口方法。(iii)[可选]提供管理父节点对象的接口方法。

    (I)Leaf(树形结构的叶节点)

    (II)Component的实现子类

    (III)Composite(树形结构的枝节点)

    (IV)Component的实现子类

    24.Decorator装饰模式<结构型模式>:

    (1)动机:过度地使用了继承来扩展对象的功能,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。

    (2)意图:动态地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活。

    (3)通过采用组合、而非继承的手法,Decorator模式实现了在运行时动态地扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。

    (4)Component类在Decorator模式中充当抽象接口的角色,不应该去实现具体的行为。而且Decorator类对于Component类应该透明-----换言之Component类无需知道Decorator类,Decorator类是从外部来扩张Component类的功能。

    (5)Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。我们可以使用一个或者多个Decorator对象来“装饰”一个Component对象,且装饰后的对象仍然是一个Component对象。

    (6)Decorator模式并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方面上的扩展功能”---是为“装饰”的含义。

    (7)装饰(Decorator)模式又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。

    (8)装饰模式的结构:

    (9)装饰模式的角色和职责:

    (I)抽象组件角色:一个抽象接口,是被装饰类和装饰类的父接口。

    (II)具体组件角色:为抽象组件的实现类。

    (III)抽象装饰角色:包含一个组件的引用,并定义了与抽象组件一致的接口。

    (IV)具体装饰角色:为抽象装饰角色的实现类。负责具体的装饰。

    (10)装饰模式-----“给喜欢用继承的人一个全新的设计眼界”。动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

    (11)装饰者会将扩展的功能,与原有的功能分离。而且,它将扩展功能的结构,与原有对象的结构分离。而继承则将把这两个结构混淆在一起。

    (12)装饰模式相比于继承的灵活性,其一体现在:动态性。新增功能后可以灵活撤销,不会改动太多代码。另外,为一批“兄弟类”增加功能时,首先装饰模式。

    25.Facade外观模式

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

    (2)从客户程序的角度来看,Facade模式不仅简化了整个组件系统的接口,同时对于组件内部与外部客户程序来说,从某种程度上也达到了一种“解耦”的效果---内部子系统的任何变化不会影响到Facade接口的变化。

    (3)Facade设计模式更注重从架构的层级去看整个系统,而不是单个类的层次。Facade很多时候更是一种架构设计模式。

    (4)注意区分Facade模式、Adapter模式、Bridge模式与Decorator模式。Facade模式注重简化接口,Adapter模式注重转换接口,Bridge模式注重分离接口(抽象)与其实现,Decorator模式注重稳定接口的前提下为对象扩展功能。

    (5)Facade模式也叫外观模式,是由GoF提出的23种设计模式中的一种。Facade模式为一组具有类似功能的类群,比如类库,子系统等等,提供一个一致的简单的界面。这个一致的简单的界面被称作Facade

    (6)外观模式的结构:

    (7)外观模式的角色和职责

    (1)Facade:位调用方定义简单的调用接口。

    (2)Clients:调用者。通过Facade接口调用提供某功能的内部类群。

    (3)Packages:功能提供者。指提供功能的类群(模块或子系统)。

    26.面向对象的代价:面向对象很好得解决了系统抽象性的问题,同时在大多数情况下,也不会损及系统的性能。但是,在某些特殊的应用中下,由于对象的数量太大,采用面向对象会给系统带来难以承受的内存开销。比如图形应用中的图元等对象、字处理应用中的字符对象等。

    27.Flyweight享元模式

    (1)动机:采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行时代价---主要指内存需求方面的代价。

    (2)意图:运用共享技术有效得支持大量细粒度的对象。

    (3)面向对象很好地解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。FlyWeight设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。

    (4)Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象状态的处理。

    (5)对象的数量太大从而导致对象内存开销增大-----什么样的数量才算大?这需要我们仔细的根据具体应用情况进行评估,而不能凭空臆断。

    (6)Flyweight模式也叫享元模式,是构造模式之一,它通过与其他类似对象共享数据来减小内存占用。

    (7)享元模式的构造:

    (8)享元模式的角色和职责:

    (I)抽象享元角色:所有具体享元类的父类,规定一些需要实现的公共接口。

    (II)具体享元角色:抽象享元角色的具体实现类,并实现了抽象享元角色规定的方法。

    (III)享元工厂角色:负责创建和管理享元角色。

    (9)减少内存开销

    (10)享元模式,即在大量数据量的情况下,为了减少内存占用,把对象中相同的部分抽象出来。类似于:在关系型数据库中,利用外键引用来减少数据库冗余。

    (11)C#中的字符串共享机制,就是典型的享元模式(两个变量,定义相同的字符串,将会指向同一个内存地址)

    28.简单工厂模式

    (1)简单工厂模式属于类的创建模式,又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

    (2)模式中包含的角色及其职责

    (I)工厂(Creator)角色:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。

    (II)抽象(Product)角色:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所有的公共接口。

    (III)具体产品(Concrete Product)角色:简单工厂模式所创建的具体实例对象。

    (3)简单工厂模式的优缺点:在这个模式中,工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于这个软件系统结构的优化。

    (4)简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高类聚”方面做得并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做出相应的修改,扩展性并不很好。

    29.工厂方法模式

    (1)工厂方法模式同样属于类的创建型模式又被称为多态工厂模式。工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

    (2)工厂方法模式中包含的角色及其职责

    (I)抽象工厂(Creator)角色:工厂方法模式的核心,任何工厂类都必须实现这个接口。

    (II)具体工厂(Concrete Creator)角色:具体工厂类是抽象工厂的一个实现,负责实例化产品对象。

    (III)抽象(Product)角色:工厂方法模式所创建的多有对象的父类,它负责描述所有实例所共有的公共接口。

    (IV)具体产品(Concrete Product)角色:工厂方法模式所创建的具体实例对象。

    (3)工厂方法模式和简单工厂模式比较:

    (I)工厂方法模式与简单工厂模式在结构上的不同不是很明显。工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。

    (2)工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。

    (3)当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不西药修改客户端,很好的符合了“开放-封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。

    (4)工厂方法模式退化后可以演变成简单工厂模式。

    30.Proxy代理模式

    (1)动机:在面向对象系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问会给使用者、或者系统结构带来很多麻烦。如何在不失去透明操作对象的同时来管理/控制这些对象特有的复杂性?增加一层间接层是软件开发中常见的解决方式。

    (2)Proxy模式又叫代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问。所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须同归代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。

    (3)代理模式的结构:

    (3)代理模式的角色和职责

    (1)subject(抽象主题角色):真实主题与代理主题的共同接口。

    (2)RealSubject(真实主题角色):定义了代理角色所代表的真实对象。

    (3)Proxy(代理主题角色):含有对真实主题角色的引用,代理角色通常在将客户端调用传递给真实主题对象之前或者之后执行某些操作,而不是单纯返回真实的对象。

    (4)动态代理

    (I)InvocationHandler接口

    (II)invoke方法

    (III)Proxy.newProxyInstance();

    31.抽象工厂模式

    (1)抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。

    (2)模式中包含的角色及其职责

    (I)抽象工厂(Creator)角色:抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个接口。

    (2)具体工厂(Concrete Creator)角色:具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。

    (3)抽象(Product)角色:抽象模式所创建的多有对象的父类,它负责描述实例所共有的公共接口。

    (4)具体产品(Concrete Product)角色:抽象模式所创建的具体实例对象。

    (3)抽象工厂中方法对应产品结构,具体工厂对应产品族。

    32.单例模式:

    (1)单例模式是一种对象创建模式,使用单例模式,可以保证为一个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在一个实例对象。

    (2)其实,GoF对单例模式的定义是:保证一个类、只有一个实例存在,同时提供能对该实例加以访问的全局访问方法。

    (3)为什么要使用单例模式?

    在应用系统开发中,我们常常有以下需求:

    (I)在多个线程之间,比如servlet环境,共享同一个资源或者操作同一个对象。

    (2)在整个程序空间使用全局变量,共享资源。

    (3)大规模系统中,为了性能的考虑,需要对节省对象的创建时间等等。

    因为Singleton模式可以保证为一个类只生成唯一的实例对象,所以这些情况,Singleton模式就派上用场了。

    (4)单例模式实现:

    (I)饿汉式

    (II)懒汉式

    (III)双重检查

    33.Strategy策略模式:

    (1)Strategy模式也叫策略模式是行为模式之一,它对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户端决定(策略)。Strategy模式主要用来平滑地处理算法的切换。

    (2)策略模式的结构:

    (3)策略模式的角色和职责:

    (I)Strategy:策略(算法)抽象。

    (II)ConcreteStrategy:各种策略(算法)的具体实现。

    (III)Context:策略的外部封装类,或者说策略的容器类。根据不同策略执行不同的行为。策略由外部环境决定。

    (4)Strategy策略模式的优点有:

    (I)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码。

    (II)策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。

    (III)使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。

    (5)策略模式的缺点:

    (I)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。

    (II)策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

    34.Observer观察者模式

    (1)Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

    (2)观察者模式的结构

    (3)观察者模式的角色和职责

    (1)Subject(被观察者):被观察的对象。当需要被观察的状态发生变化时,需要通知对列中所有观察者对象。Subject需要维持(添加,删除,通知)一个观察者对象的队列列表。

    (2)ConcreteSubject:被观察者的具体实现。包含一些基本的属性状态及其操作。

    (3)Observer(观察者):接口或抽象类。当Subject的状态发生变化时,Observer对象将通过一个callback函数得到通知。

    (4)ConcreteObserver:观察者的具体实现。得到通知后将完成一些具体的业务逻辑处理。

    (5)Observer观察者模式的典型应用

    (I)侦听事件驱动程序设计中的外部事件

    (II)侦听/监听某个对象的状态变化

    (III)发布者/订阅者(publisher/subscriber)模式中,当一个外部事件(新的产品,消息的出现等等)被触发时,通知邮件列表中的订阅者。

    35.Interpreter模式(解释器模式)

    (1)Interpreter模式也叫适配器模式,是行为模式之一,它是一种特殊的设计模式,它建立一个适配器,对于特定的计算机程序设计语言,用来解释预先定义的文法。简单地说,Interpreter模式是一种简单的语法解释器架构。

    (2)解释器模式应用场景

    当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式效果最好:

    (I)该文法简单对于复杂的文法,文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。

    (II)效率不是一个关键问题,最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先将它们转换成另一种现实。例如,正则表达式通常被转换成状态机。但即使在这种情况下,转换器仍可用解释器模式实现,该模式仍是可有用的。

    (III)解释器模式的结构:

    (IV)解释器模式的角色和职责

    (I)Context:解释器上下文环境类。用来存储解释器的上下文环境,比如需要解释的文法等。

    (II)AbstractExpression:解释器抽象类。

    (III)ConcreteExpression:解释器具体实现类。

    36.Mediator模式(中介者模式)

    (1)Mediator模式也叫中介者模式,是由GoF提出的23种软件设计模式的一种。Mediator模式是行为之一,在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互,Mediator对象起着控制器的作用。

    (2)中介者模式的结构:

    (3)中介者模式的角色和职责

    (I)mediator:中介者类的抽象父类。

    (II)concreteMediator:具体的中介者类。

    (III)colleague:关联类的抽象父类。

    (IV)concreteColleague:具体的关联类。

    (4)中介者模式的优点:

    (I)将系统按功能分割成更小的对象,符合类的最小设计原则。

    (II)对关联对象的集中控制

    (III)减小类的耦合程度,明确类之间的相互关系:当类之间的关系过于复杂时,其中任何一个类的修改都会影响到其他类,不符合类的设计的开闭原则,而Mediator模式将原来相互依存的多对多的类之间的关系简化为Mediator控制类与其他关联类的一对多的关系,当其中一个类修改时,可以对其他关联类不产生影响(即使有修改,也集中在Mediator控制类)。

    (IV)有利于提高类的重用性。

    37.Chain of Responsibility(CoR)模式(职责链模式)(职责连锁模式)

    (1)CoR模式是行为模式之一,该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的对象之间像链条一样紧密相连,所以被称作职责链模式。

    (2)职责链模式的基本条件:

    要实现Chain of Responsibility模式,需要满足该模式的基本条件:

    (I)对象链的组织。需要将某任务的所有职责执行对象以链的形式加以组织。

    (II)消息或请求的传递。将消息或请求沿着对象链传递,以让处于对象链中的对象得到处理机会。

    (III)处于对象链中的对象的职责分配。不同的对象完成不同的职责。

    (IV)任务的完成。处于对象链的末尾的对象结束任务并停止消息或请求的继续传递。

    (3)职责链模式的结构:

    (4)职责链模式的角色和职责:

    (I)Handler:处理类的抽象父类。

    (2)concreteHandler:具体的处理类。

    (5)职责链模式的优点:

    (I)责任的分担。每个类只需要处理自己改处理的工作(不该处理的传递给下一个对象完成),明确各类的责任范围,符合类的最小封装原则。

    (II)可以根据需要自由组合工作流程。如工作流程发生变化,可以通过重新分配对象链便可适应新的工作流程。

    (III)类与类之间可以以松耦合的形式加以组织。

    (6)职责链模式的缺点:

    因为处理时以链的形式在对象间传递消息,根据实现方式不同,有可能会影响处理的速度。

    38.Iterator模式(迭代模式)

    (1)Iterator模式也叫迭代模式,是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式。

    (2)不适用迭代模式的应用:

    在应用Iterator模式之前,首先应该明白Iterator模式来解决什么问题。或者说,如果不使用Iterator模式,会存在什么问题。

    (I)由容器自己实现顺序遍历。直接在容器类里直接添加顺序遍历方法。

    (II)让调用者自己实现遍历。直接暴露数据细节给外部。

    (3)不适用迭代模式的缺点:

    以上方法I与方法II都可以实现对遍历,这样有什么问题呢?

    (I)容器类承担了太多功能:一方面需要提供添加删除等本身应有的功能;一方面还需要提供遍历访问功能。

    (II)往往容器在实现遍历的过程中,需要保持遍历状态,当跟元素的添加删除等功能夹杂在一起,很容易引起混乱和程序运行错误等。

    (4)使用迭代模式的应用

    Iterator模式就是为了有效地处理按顺序进行遍历访问的一种设计模式,简单地说,Iterator模式提供一种有效的方法,可以屏蔽聚集对象集合的容器类的实现细节,而能对容器内包含的对象按顺序进行有效的遍历访问。

    所以,Iterator模式的应用场景可以归纳为满足以下几个条件:

    (I)访问容器中包含的内部对象。

    (II)按顺序访问

    (5)迭代模式的结构:

    (6)迭代模式的角色和职责

    (I)Iterator(迭代器接口):该接口必须定义实现迭代功能的最小定义方法集。

    (II)ConcreteIterator(迭代器实现类):迭代器接口Iterator的实现类。可以根据具体情况加以实现。

    (III)Aggregate(容器接口):定义基本功能以及提供类似Iterator iterator()的方法。

    (IV)concreteAggregate(容器实现类):容器接口的实现类。必须实现Iterator iterator()方法。

    (7)迭代模式的优点:

    (I)实现功能分离,简化容器接口。让容器只实现本身的基本功能,把迭代功能委让给外部类实现,符合类的设计原则。

    (II)隐藏容器的实现细节。

    (III)为容器或其子容器提供了一个统一接口,一方面方便调用;另一方面使得调用者不必关注迭代器的实现细节。

    (IV)可以为容器或其子容器实现不同的迭代方法或多个迭代方法。

    39:Template Method 模板方式模式

    (1)Template Method模板也叫模板方法模式,是行为模式之一,它把具有特定步骤算法中的某些必要的处理委让给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为。

    (2)模板方法模式的应用场景

    Template Mothod模式一般应用在具体以下条件的应用中:

    (I)具有统一 的操作步骤或者过程

    (II)具有不同的操作细节

    (III)存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同。

    (3)模板方法模式的结构:

    (4)模板方法模式的角色和职责

    (I)AbstractClass:抽象类的父类

    (II)ConcreteClass:具体的实现子类

    (III)templateMethod():模板方法

    (IV)method1()与method2():具体步骤方法

    40.Memento模式(备忘录模式)

    (1)Memento模式是行为模式之一,它的作用是保存对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。

    (2)备忘录模式的应用场景

    如果一个对象需要保存状态并可通过undo或rollback等操作恢复到以前的状态时,可以使用Memento模式。

    (I)一个类需要保存它的对象的状态(相当于Originator角色)

    (II)设计一个类,该类只是用来保存上述对象的状态(相当于Memento角色)

    (III)需要的时候,Caretaker角色要求Originator返回一个Memento并加以保存

    (IV)undo或rollback操作时,通过Caretaker保存的Memento恢复Originator对象的状态。

    (3)备忘录模式的结构

    (4)备忘录模式的角色和职责

    (I)Originator(原生者):需要被保存状态以便恢复的那个对象。

    (II)Memento(备忘录):该对象由Originator创建,主要用来保存Originator的内部状态。

    (III)Caretaker(管理者):负责在适当的时间保存/恢复Originator对象的状态。

    41.状态State模式<行为型模式>

    (1)State模式是行为设计模式的一种。State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样。

    (2)状态模式的应用场景

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

    (3)状态模式的结构

    (4)状态模式的角色和职责

    (I)Context:用户对象:

    拥有一个State类型的成员,以标识对象的当前状态;

    (II)State:接口或基类:

    封装与Context的特定状态相关的行为;

    (III)ConcreteState:接口实现类或子类:

    实现了一个与COntext某个状态相关的行为

    (5)状态模式的核心是封装,状态的变更引起了行为的变更,从外部看起来就好像这个对象对应的类发生了改变一样。

    (6)状态模式的例子:例如权限设计。一个对象在不同的状态下,执行相同的操作,也会产生不同的结果。

    42.Command模式(命令模式)

    (1)Command模式是行为设计模式的一种。Command模式通过被称为Command的类封装了对目标对象的调用行为以及调用参数。

    (2)命令模式的应用场景

    在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。

    但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。

    整个调用过程比较繁杂,或者存在多处这种调用。这时,使用Command类对该调用加以封装,以便于功能在利用。

    调用前后需要对调用参数进行某些处理。

    调用前后需要进行额外处理,比如日志,缓存,记录历史操作等。

    (3)命令模式的结构:

    (4)命令模式的角色和职责

    (I)Command:Command抽象类。

    (II)ConcreteCommand:Command的具体实现类。

    (III)Receiver:需要被调用的目标对象。

    (IV)Invorker:通过Invorker执行Command对象。

    43.Visitor模式(访问者模式)

    (1)Visitor模式是行为模式之一,它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况在,增加新的操作。

    (2)访问者模式的结构:

    (3)访问者模式的角色和职责

    (I)访问者角色(Visitor):

    为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。

    (II)具体访问者角色(Concrete Visitor):

    实现每个由访问者角色(Visitor)声明的操作。

    (III)元素角色(Element):

    定义一个Accept操作,它以一个访问者为参数。

    (IV)具体元素角色(ConcreteElement):实现有元素角色提供的Accept操作。

    (V)对象结构角色(Object Structure):

    这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素;可以提供一个高层的结构以允许该访问者访问它的元素;可以是一个集合(组合模式)或是一个集合,如一个列表或一个无序集合。

    44.Open-Closed Principle 开放封闭原则

    (1)开放封闭原则(Open-Closed Principle):一个软件实体应当对扩展开放,则修改关闭。

    (2)在设计一个模块时,应当使得这个模块可以在不被修改的前提下呗扩展。也就是说,应当可以在不必修改源代码的情况下修改这个模块的行为。

    (3)设计的目的便在于面对需求的改变而保持系统的相对未定,从而使得系统可以很容易的从一个版本升级到另一个版本。

    (4)怎样做到开放封闭原则:

    实际上,绝对封闭的系统是不存在的。无论模块时怎么封闭,到最后,总还是有一些无法封闭的变化。而我们的思路就是:既然不能做到无法封闭,那我们就应该对那些变化封闭,那些变化隔离做出选择。我们做出选择,然后将那些无法封闭的变化抽象出来,进行隔离,允许扩展,尽可能的减少系统的开发。当系统变化来临时,我们要及时的做出反应。

    我们并不害怕改变的到来。当变化到来时,我们首先需要做的不是修改代码,而是尽可能的将变化抽象出来进行隔离,然后进行扩展。面对需求的变化,对程序的修改应该是尽可能添加代码来实现,而不是通过修改代码来实现。

    实际上,变化或者可能的变化来的越早,抽象就越容易,相对的,代码的维护也就越容易;而当项目接近于完成而来的需求变化,则会使抽象变得很困难---这个困难,并不是抽象本身的困难,抽象本身并没有困难,困难在于系统的架构已经完成,修改牵扯的方面太多而使得抽象工作变得很困难。

    (5)开放封闭原则的优越性:

    (I)通过扩展已有的系统软件,可以提供新的行为,以满足对软件的新需求,是变化中的软件有一定的适应性和灵活性。

    (II)已有的软件模块,特别是最重要的抽象模块不能在修改,这就使变化中的软件系统有一定的稳定性和延续性。

    45.Single Responsibility Principle 单一职责原则

    (1)单一职责原则(Single Responsibility Principle):就一个类而言,应该仅有一个引起它变化的原因。

    (2)每一个职责都是一个变化的轴线,当需求变化时会反映为类的职责的变化。如果一个类承担的职责多多于一个,那么引起它变化的原因就有多个。一个职责的变化甚至可能会消弱或者抑制类完成其他职责的能力,从而导致脆弱的设计。

    46.Liskov Substitution Principle里氏代换原则

    (1)Liskov Subsitution Principle:一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类和子类对象的区别。也就是说,在软件里面,把父类替换成它的子类,程序的行为没有变化。

    (2)反过来的代换不成立:一个软件实体如果使用的是一个子类的话,那么它不能适用于其父类。

    (3)能够骗过Java编辑器,真的符合里氏代换原则吗?答案是否定的。

    47.Dependence Inversion Principle依赖倒转原则

    (1)传统的过程式设计倾向于使高层次的模块依赖于低层次的模块,抽象层依赖于具体的层次。

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

    (I)抽象不应该依赖于细节,细节应该依赖于抽象。

    (II)高层模块不依赖底层模块,两者都依赖抽象。

    (3)怎样做到依赖倒转

    (I)工厂方法模式

    (II)模块方法模式

    (III)迭代子模块

    48.Law of Demeter:迪米特法则

    (1)迪米特法则(Law of Demeter)又叫作最少知识原则,也就是说,一个对象应当对其他对象尽可能少的了解。

    (2)迪米特法则最初是用来作为面向对象的系统设计风格的一种法则,于1987年秋天由lan holland在美国东北大学为一个叫做迪米特的项目设计提出的。

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

    (4)迪米特法则和设计模式

    (I)外观模式

    (II)中介者模式

    49.UML类图

    (1)描述类的类图

    (2)抽象类

    (3)接口

    (4)对象

    (5)一般化关系(继承)

    (6)关联关系

    (7)关联基数

    (8)聚合关系:聚合关系是关联关系的一种,表示的是整体与个体之间的关系

    (9)合成关系:合成关系是关联关系的一种,比聚合关系更强,它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期,合成关系不能共享。

    (10)依赖关系:依赖也是类与类之间的连接,依赖总是单向的。依赖关系表示一个类依赖于另一个类的定义。

    50.设计模式的分类

    51.对象行为与操作对象

    所谓对象行为和操作对象,需要三方面内容

    (1)操作过程:一般表现为一个方法。该方法接受一个对象或者组合类型的参数,然后对这个对象或者组合进行操作,例如修改属性、状态或者结构等。

    (2)操作的对象或组合:会作为实参传入操作过程,会被操作过程修改属性、状态或者结构等。

    (3)受影响的对象或组合:由于修改其他对象或者组合,可能会影响到另外的对象或者组合,因此需要考虑这种影响关系,一般会用通知或者消息订阅的方式实现。

    52.C#几个模式案例

    C#语言描写
    //工厂模式
    using System;
    namespace dNetApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Compute compute=Factory.GetCompte("+");
                compute.DoCompute(10,15);
                
                Console.ReadLine();
            }
        }
        
        abstract class Compute
        {
            public abstract void Docompute(int n1,int n2);
        }
        
        class AddCompute:Compute
        {
            public override void DoCompute(int n1,int n2)
            {
                Console.WriteLine(n1+n2);
            }
        }
        class SubtractCompute:Compute
        {
            public override void DoCompute(int n1,int n2)
            {
                Console.WriteLine(n1-n2);
            }
        }
        class MultiCompute:Compute
        {
            public override void DoCompute(int n1,int n2)
            {
                Console.WriteLine(n1*n2);
            }
        }
        
        class Factory
        {
            public static Compute GetCompte(string sysbol)
            {
                switch(sysbol)
                {
                    case "+":
                        return new AddCompute();
                    case  "-":
                        return new SubStractCompute();
                    case "*":
                        return new MultiCompute();
                    default:
                        return null;
                    
                }
            }
        }
        
    }
    //单例模式
    using System;
    namespace dNetApp1
    {
        //单例模式:让类自身负责保存它的唯一实例,这个类可以保证没有其他实例可以被创建
        class Program
        {
            static void Main(string[] args)
            {
                Singleton s1=Singleton.GetInstance();
                Singleton s2=Singleton.GetInstance();
                
                if(s1==s2)
                {
                    Console.WriteLine("两个实例相同");
                }
                
                Console.Read);
            }
        }
        class Singleton
        {
            private static Singleton instance;
            
            private Singleton()//构造函数为private类型,这就堵死了外界利用new创建此类实例的可能
            {
            }
            public static Singleton GetInstance()
            {
                if(instance==null)
                {
                    instance=new Singleton();//内部可以通过private构造函数创建实例
                }
                return instance;
            }
        }
    }
    
    //创建者模式
    using System;
    namespace dNetApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Director director=new Director();
                Builder b1=new ConcreteBuilder1();
                builder b2=new ConcreteBuilder2();
                
                director.Construct(b1);
                Product p1=b1.GetResult();
                p1.Show();
                
                director.Construct(b2);
                Product p2=b2.GetResult();
                p2.Show();
                
                ConSole.Read();
            } 
        }
        //具体的产品类,定义产品的结构,包含若干个part
        class Product
        {
            IList<string> parts=new List<string>();
            public void Add(string part)
            {
                parts.Add(part);
            }
            
            public void Show()
            {
                Console.WriteLine("Product show:");
                
                foreach(string part in parts)
                {
                    Console.WriteLine(part);
                }
            }
        }
        //抽象:
        //(1)创建产品的全部步骤(不一定全用上)
        //(2)获取产品对象的接口
        abstract class Builder
        {
            public abstract void BuilderPartA();//发动机
            public abstract void BuilderPartB();//变速箱
            public abstract Product GetResult();
        }
        
        //具体
        //通过"part A"和“part B”创建对象
        class ConcreteBuilder1:Builder
        {
            private Product product=new Product();//初始化一个产品对象
            public override void BuilderPartA()
            {
                product.Add("part A(柴油发电机)");
            }
            public override void BuilderPartB()
            {
                product.Add("part B(手机变速箱)");
            }
            public override Product GetResult()
            {
                return product;
            }
        }
        
        //具体
        //通过"part X"和“part Y”创建对象
        class ConcreteBuilder2:Builder
        {
            private Product product=new Product();//初始化一个产品对象
            public override void BuilderPartA()
            {
                product.Add("part X(柴油发电机)");
            }
            public override void BuilderPartB()
            {
                product.Add("part Y(手机变速箱)");
            }
            public override Product GetResult()
            {
                return product;
            }
        }
        //定义明确的创建过程
        class Director
        {
            public void Construct(Builder builder)
            {
                builder.BuilderPartA();//发送机
                builder.BuilderPartB();//变速箱
            }
        }
    }
    //职责链模式
    using System;
    namespace dNetApp1
    {
        //职责链模式:用对个对象的链模式,来取代大量的if....else ...代码,从而隔离解耦
        class Program
        {
            static void Main(string[] args)
            {
                Handler h1=new ConcreteHandler1();
                Handler h2=new ConcreteBuilder2();
                Handler h3=new ConcreteBuilder3();
                
                h1.SetSuccessor(h2);
                h2.SetSuccessor(h3);
                
                int[] request={5,15,25};
                
                foreach (int r in requests)
                {
                    h1.RequestHandler(r);
                }
                ConSole.Read();
            } 
        }
        abstract class Handler
        {
            protected Handler successor;
            //设置继承者
            public void SetSuccessor(Handler successor)
            {
                this.successor=successor;
            }
            //处理请求的抽象方法
            public abstract void RequestHandler(int request);
        }
        //实现:步骤1
        class ConcreteHandler1:Handler
        {
            public override void RequestHandler(int request)
            {
                if(request>=0&&request<10)//处理0~10的情况
                {
                    Console.WriteLine("{0}处理请求{1}",this.GetType().Name,request);
                }else if(successor!=null)
                {
                    successor.RequestHandler(request);//其他情况,移植下一步
                }
            }
        }
        //实现:步骤2
        class ConcreteHandler2:Handler
        {
            public override void RequestHandler(int request)
            {
                if(request>=10&&request<20)//处理10~20的情况
                {
                    Console.WriteLine("{0}处理请求{1}",this.GetType().Name,request);
                }else if(successor!=null)
                {
                    successor.RequestHandler(request);//其他情况,移植下一步
                }
            }
        }
            //实现:步骤3
        class ConcreteHandler3:Handler
        {
            public override void RequestHandler(int request)
            {
                if(request>=20&&request<30)//处理10~20的情况
                {
                    Console.WriteLine("{0}处理请求{1}",this.GetType().Name,request);
                }else if(successor!=null)
                {
                    successor.RequestHandler(request);//其他情况,移植下一步
                }
            }
        }
    }
    
    //状态模式
    using System;
    namespace dNetApp1
    {
        //状态模式:
        //Context类有若干个状态,但不知道这些状态的具体(解耦)
        //于是将“状态”抽象为一个State类,具体的状态交给子类实现
        //Context的状态,就由一个State类型的对象来表示
        
        class Program
        {
            static void Main(string[] args)
            {
                Context c=new Context(new ConcreteStateA());//c对象的默认状态是new ConcreteStateA()(“状态”就是一个对象)
                ConSole.Read();
            } 
        }
        //抽象,状态类
        abstract class State
        {
            public abstract void Handler(Context context);
        }
        //具体,状态类
        class ConcreteStateA:State
        {
            public override void Handle(Context context)
            {
                context.State=new ConcreteStateB();//将context对象的状态该为new ConcreteStateB()
            }
        }
            //具体,状态类
        class ConcreteStateB:State
        {
            public override void Handle(Context context)
            {
                context.State=new ConcreteStateA();//将context对象的状态该为new ConcreteStateA()
            }
        }
        
        class Context
        {
            private State state;
            public Context(State state)
            {
                this.state=state;
            }
            public State State
            {
                get{return state;}
                set
                {
                    state=value;
                    ConSole.WriteLine("当前状态:"+state.GetType().Name);
                }
            }
            public void Request()
            {
                state.Handle(this);
            }
        }
    View Code

    53.设计模式描述了对象如何进行通信才能不牵涉相互的数据模型和方法。保持这种独立性一直是一个好的面向对象程序设计的目标。

    (1)创建型模式:通常和对象的创建有关,涉及到对象实例化的方式。(5种)

    (2)行为型模式:通常和对象间通信有关。(11种)

    (3)结构型模式:描述的是如何组合类和对象以获取更大的结构(7种)。注:类模式描述的是如何使用继承提供更有用的程序接口。而对象模式描述的是如何通过使用对象组合将对象包含在其他对象里,将对象组合成更大的一个结构。

  • 相关阅读:
    PHP的注释规范
    IP地址与,域名,DNS服务器,端口号的联系与概念
    转: CentOS上安装LAMP之第一步:Apache环境及安装过程报错解决方案(纯净系统环境)
    转:VMware中CentOS配置静态IP进行网络访问(NAT方式和桥接模式)
    虚拟主机详细的配置
    PHP操作MySQL
    【优化】EXPLAIN--type
    数据库范式
    【优化】碎片OPTIMIZE
    【原理】原理与优化(二)
  • 原文地址:https://www.cnblogs.com/heisaijuzhen/p/4348693.html
Copyright © 2011-2022 走看看