目录
1. 抽象工厂模式
参考《大话设计模式》第十五章
1.0 《设计模式》摘录
-
抽象工厂意图:提供一个创建一系列相关或相互依赖对象的接口,但不指定这个接口的实现类
-
问题:建立一个系统能够支持多种用户界面风格
-
解决:用不同的界面对象,把创建这些界面对象的工作委托给另一个对象来完成
-
抽象工厂:
窗口工厂类,这个类声明了一个接口,接口中定义一个抽象的定义了用于创建各种窗口部件(例如滚动条,按钮等等)的方法的型构。
为每种风格定义具体的窗口工厂类,作为抽象窗口工厂的子类,其中定义创建各种窗口部件的方法。
在具体工厂类的这些方法中再指定创建哪个类的实例对象。 -
优点:
客户代码和实现具体部件的一系列类相互独立,只知道abstract
容易更换部件系列
容易增加新的部件系列
容易保持部件的一致性
一个ConcreteFactory只创建同一系列的部件 -
缺点
不容易增加新的部件(例如原来没有Toolbar,现在要增加Toolbar ),否则就要改变AbstractFacory的接口
1.1 问题
用户可能用两种类型的数据库,这两种数据库有类似的方法,但如果一开始声明对象时,固定了它使用 SQL Server 数据库:SqlserverUser su=new SqlserverUser()
,那么要是后面需要改成Access数据库,它调用的各种方法都需要改变,需要修改的代码量很大。比如添加用户操作:su.Insert(User),两种类型的数据库都是执行这个操作,但具体实现的代码不同,这样需要全部改变。
此问题的特点:有多种模式可以用,但不同模式又有相似操作。虽然不同模式实现相似操作的具体代码不同,但对用户来说达到的效果是一样的。
1.2 UML图和代码
-
定义:抽象工厂模式——提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
-
UML图
对上述问题的解决方法:
对用户来说:他只看得到抽象接口IUser,不用知道具体实现类(SqlserverUser和AccessUser)。这意味着他知道有哪些操作(IUer告诉他的),但不用考虑是在Sqlserver还是Access的环境中使用操作。那么当要从Sqlserver数据库改到Access数据库时,只要改变传给工厂的指令,但用户端的操作代码都不用变(操作是固定的,IUser中定义了固定的操作)。
对工厂来说:首先告诉工厂是在哪个环境,工厂根据指定的环境创造具体工厂(不同的具体工厂会创造不同的操作组合)。然后具体工厂将这些操作组合在一起,返回给用户。这样用户不用去挑选环境对应的各个操作,直接从工厂那里拿到一整套的操作。
-
代码
-
IUser和IDocument
interface IUser//定义了关于User的操作 { void Insert(User user); User GetUser(int id); } interface IDepartment//定义了关于department的操作 { void Insert(Department department); Department GetDepartment(int id); }
-
IUser和IDepartment的具体实现类:
//SqlserverUser,用于访问 SQL Server 的 User class SqlserverUser implements Iuser { public void Insert(User user) { ... } public void GetUser(int id) { ... } } //AccessUser,用于访问Access 的 User class AccessUser implements Iuser { public void Insert(User user) { ... } public void GetUser(int id) { ... } } //SqlserverDepartment,用于访问 SQL Server 的 Department class SqIserverDepartment implements IDepartment { ... } //AccessDepartment,用于访问Access 的 Department class AccessrDepartment implements IDepartment { .