一、Abstract Factory(抽象工厂)
1.意图:提供一个创建一系列相关或相互依赖对象的借口,而无需指定它们具体的类。
2.结构:
3.示例:
a.gof示例: 类MazeFactory创建迷宫的组件,创建房间、墙壁和房间之间的门。而在Main中,将MazeFactory作为参数传入。那么系统就知道要创建哪一个Factory。
现在需要扩展一个施了魔法的迷宫的工厂,就可以让EnchantedMazeFactory继承MazeFactory作为参数传入main就行了。
b.大话示例:
关于系统更换数据库的问题,有一个Access数据库和SqlServer数据库,分别都要对数据表进行操作。
interface IDepartment { void Insert(Department department); Department GetDepartment(int id); } class SqlserverDepartment: IDepartment { public void Insert(..) ... public Department GetDepartment() ... } class AccessDepartment : IDepartment { public void Insert() ...; public Department GetDepartment() ...; } //the same as IUser; interface IFactory { IUser CreateUser(); IDepartment CreateDepartment(); } class SqlserverFactory: IFactory { public IUser CreateUser() { return new SqlServerUser(); } public IDepartment CreateDepartment() { return new SqlserverDepartment(); } } class AccessFactory : IFactory { public IUser CreateUser() { return new AccessUser(); } public IUser CreateDepartment() { return new AccessDepartment(); } } void Main(string[] args) { User user = new User(); Department dept = new Department(); //IFactory factory = new SqlServerFactory(); IFactory factory = new AccessFactory(); IUser iu = factory.CreateUser(); iu.Insert(user); iu.GetUser(1); IDepartment id = factory.CreateDepartment(); id.Insert(dept); id.GetDepartment(1); }
以上代码很好的体现除了抽象工厂的作用。
4.体会:Abstract Factory也就是将一个创建过程抽象成一个参数放入main的创建中,参数是灵活的。
5.优点与缺点:
优点:易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
它让具体的创建实例过程与客户端分离,客户端是通过他们的抽象借口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
二、Builder(生成器)
1.意图:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
2.结构:
3.示例:
a.Gof示例:定义一个生成器对象MazeBuilder。在Main中使用CreateMaze(MazeBuilder &builder)来创建迷宫。而StandardMazeBuilder与CountingMazeBuilder继承MazeBuilder.这些Builder不创建整体的迷宫。只创建相应的构建,最后通过Builder中的getMaze()返回一个由各个构件组成的一个整体的迷宫。
b.大话示例:以一步一步画一个小人为例。
abstract class PersonBuilder { protected Graphics g; protected Pen p; Public PersonBuilder(Graphics g,Pen p) { this.g = g; this.p = p; } public abstract void BuildHead(); public abstract void BuildBody(); public abstract void BuildArmLeft(); public abstract void BuildArmRight(); public abstract void BuildLegLeft(); public abstract void BuildLegRight(); } class PersonThinBuilder : PersonBuilder { public PersonThinBuilder(....):base(..) .. public override void BuildHead() { } public override void BuildBody(){...} public override void BuildArmLeft(){...} public override void BuildArmRight(){...} public override void BuildLegLeft(){...} public override void BuildLegRight(){...} } //The Same as the PersonFatBuilder; class PersonDirector { private PersonBuilder pb; public PersonDirector(PersonBuilder pb) { this.pb = pb; } public void CreatePerson(){ pb.BuildHead(); pb.BuildBody(); pb.BuildArmLeft(); pb.BuildLegLeft(); pb.BuildLegRight(); } } void Main(){ Pen p ... PersonThinBuilder ptb = new PersonThinBuilder(CreateGraphics(),p); PersonDirector pdThin = new PersonDirector(ptb); pbThin.CreatePerson(); PersonFatBuilder pfb = new PersonFatBuilder(CreateGraphics(),p); PersonDirector pdFat = new PersonDirector(ptb); pdFat.CreatePerson(); }
4.体会:对于AbstractFactory,其更主要的是为了多个系列的产品,且产品是立即返回的。而Builder是为了一步步构造一个复杂对象。且在最后一步返回。
而什么时候使用Builder呢?主要是用于创建一些复杂的对象,这些对象内部构建间的构造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。
5.优点与缺点:
优点就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。
缺点:也就是创建的顺序不易改变了。(可以通过条件分支来判断改变创建的顺序)。
三、Factory Method(工厂方法)
1.意图:定义一个用于创建对象的结构,让子类决定实例化哪一个类。FactoryMethod是一个类的实例化延迟到了其子类。
2.结构:
3.示例:
a.gof示例:在MazeGame定义工厂方法以创建迷宫,房间,墙壁和门对象:
每一个工厂方法返回一个给定类型的迷宫构件:
4.体会:
5.优点与缺点: