1、抽象工厂(Abstract):提供一个创建一系列或相关依赖对象的接口,而无需指定他们具体的类。
好处一:便于交换产品系列,由于具体工厂类,在一个应用程序中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂,即可使用不同的产品配置。不能防止需求不变,但是我们可以让程序改变更小;
好处二:它让具体的创建实例过程与客户端分离,客户端只是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。
2、建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。
如果,我们使用建造者模式,那么用户就只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。
客户端代码:
Director director=new Director();
Builder b1=new ConcreteBuilder();
director.Construct(b1);//里面涉及建造的过程BuilderPart()方法
Product p=b1.getResult();
p.Show();
适用:当创建复杂对象的算法应该独立于给对象的组成部分以及它们的装配方式时,
3、工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到其子类。
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现Produt1类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来实现。你要是想加功能,本来是该工厂类的,而现在是修改客户端。
4、原型模式:指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
案例:
某即时战略游戏,你训练出来各种很强的战士。
为了增加游戏的可玩性,增加了一种复制魔法。实施该魔法,可以复制任意的战士。
你会怎样考虑这个设计?
在继续阅读之前,请先认真思考并写出你的设计,这样对你更好地理解本模式将会更有帮助。
分析:
1.无疑增加一个复制的方法能解决这个问题。
2.专门写一个复制类吗?传入一个战士,然后返回一个复制的战士,这样可行吗?这样做有以下问题:
1)游戏还在设计中,战士的品种还会不断演变,每增加一个品种,或者修改某品种的战士,复制类就需要修改代码。
2)为了复制好战士,复制类需要是访问战士内部的属性,这样战士类可能需要暴露内部信息。
通过“原型”这两个中文字来理解原型模式是有点难度的,我们往往会用“原型开发”的“原型”来理解。
我们看看英文原型(Prototype)的解释:
the first design of something from which other forms are copied or developed.
原型模式的要点:
1.利用现成对象制作新的对象。
2.被复制的对象,需要实现clone(克隆)接口:Soldier newSoldier = oldSoldier.Clone();
类图如下:
说明:
1.每种战士实现自己的复制方法,自己可以访问自己的内部信息,复制起来很方便,也不需要对外暴露内部信息。
2.增加或者修改战士的种类,只需要修改该类便可,其它代码不受影响。
5、单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式可能是23种模式中最简单也被说得最多的模式了。
什么情况下可考虑用单件模式呢?
需要一致地管理全局信息时,可考虑用单例模式。
例:
某论坛需要对所有访问者显示当前在线人数、最高在线人数、今天谁生日等全局信息。
论坛很火热,我们不希望每次都要去读数据库,而希望通过一个类来管理这些信息。
你会怎样考虑这个设计?
如果每个访问者进入论坛,论坛程序都要去“运算”一下来获取这些信息,那岂不是要消耗掉大量的性能?
分析:
1.最高在线人数、今日谁生日这些信息,可以在数据库中获取,如果每一次页面刷新都去获取一次,实在是浪费性能。
2.当前在线人数在当前程序运行环境中可以获取,该数字是经常变的,有没有必要每次都重新获取呢?
单例模式的其中一种实现办法:
说明:
1.在统一的地方管理全局的信息。
2.这些全局信息供程序其它地方读取,一般情况下是读数据,而不写数据,如果要写数据还需要处理写冲突。
上例中光用单件模式还不能完全解决问题,Singleton类中应该还需要写缓存的代码,将最高在线人数、今日谁生日缓存起来,使程序不必每次去读取数据库。
单例通过在内存中唯一的Singleton保证了数据的唯一,并克服了数据冲突,但如果应用在网络负载均衡环境就会出问题。
在网络负载均衡环境中,有多台服务器跑相同的程序,每台服务器上有一个Singleton,这样就会出问题,在软件设计时需要考虑这样的情况。
在网络负载均衡环境下,程序要避免使用静态变量,对于需要共享的数据可通过统一的状态服务来处理,也就是说专门用一个服务来管理这些全局数据,所有程序从这个服务中取数据,而不要再通过Singleton的静态方法。
上面1—5模式是创建型模式:抽象工厂、工厂方法、建造者、原型、单例。其中还有一个简单工厂方法(和工厂方法的区别是:工厂类就一个,不像工厂方法,有多种工厂类,对应相应的操作类。加减乘除就是其中的最好的例子吧,现阶段。)
下面就是简单工厂模式:
如果在代码中经常要重复写这段代码,实在不太爽:
if (…...)
newObject = new TypeA(); //TypeA TypeB的父类一样。
else if (…...)
newObject = new TypeB(); //TypeA TypeB的父类一样。
……
你考虑怎样改进?
这样可不简单!用一个静态方法,根据传入参数返回所需的对象便可,在每个需要用到这个对象的地方,这样写便可:
Object newObject = ObjectBuilder.CreateObject(string type);
类图如下:
以上这个设计就是简单工厂,简单工厂不是23种模式中的一种,但在我们实际工作中经常会用到,简单工厂是管理new的最常见方法。
在程序中new对象一般没有这样简单,往往要根据不同的情况new不同的对象,并且要初始化对象,我们往往将这些工作“包装”到某个方法里面,通过这个方法直接得到需要的对象。