简单工厂、工厂方法与抽象工厂模式对比
来源:互联网 发布:传智播客 java简历 编辑:程序博客网 时间:2024/05/17 21:58
简单工厂模式(不是GoF23种设计模式之一)、工厂方法模式和抽象工厂模式均属于创建型设计模式,它们各有各的优缺点,相互之间有区别也有联系,下面来看看三者之间的对比:
模式名称
定义
优点
缺点
适用范围
简单工厂
由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
每增加一个功能,都需要对工厂类的逻辑判断进行修改。
工厂类负责创建的对象比较少,客户只知道传入了工厂类的参数,对于始何创建对象(逻辑)不关心。
工厂方法
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
由于使用了多态性,工厂方法克服了简单工厂违背开放-封闭原则的缺点,又保持了封装对象创建过程的优点。
由于每增加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。
当一个类不知道它所必须创建对象的类或一个类希望由子类来指定它所创建的对象时,当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候,可以使用工厂方法。
抽象工厂
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
1、易于交换产品系列。由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
2、它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
如果需求来自增加功能,此时,需要增加若干类,并修改相关的工厂类。
1. 一个系统要独立于它的产品的创建、组合和表示时。
2.一个系统要由多个产品系列中的一个来配置时。
3.当你要强调一系列相关的产品对象的设计以便进行联合时。
4.当你提供一个产品类库,而只想显示它们的接口而不是实现时。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Reflection; //引入反射,必须要写using System.Configuration;namespace 抽象工厂模式2用简单工厂来改进抽象工厂{ class DataAccess { #region 未使用反射 //private static readonly string db = "Sqlserver"; //数据库名称,可替换为Access ////private static readonly string db = "Access"; //public static IUser CreateUser() //{ // IUser result = null; // switch (db) //由于db的事先设置,所以此处可以根据选择实例化出相应的对象 // { // case "Sqlserver": // result = new SqlserverUser(); // break; // case "Access": // result = new AccessUser(); // break; // } // return result; //} //public static IDepartment CreateDepartment() //{ // IDepartment result = null; // switch (db) // { // case "Sqlserver": // result = new SqlserverDepartment(); // break; // case "Access": // result = new AccessDepartment(); // break; // } // return result; //} #endregion private static readonly string AssemblyName = "抽象工厂模式2用简单工厂来改进抽象工厂"; //AssemblyName就是本解决方案的名称 //只使用反射 // private static readonly string db = "Sqlserver"; //private static readlonly string db="Access"; //数据库名称可以更换为Access //使用反射+配置文件(使用前需要从引用中添加system.configuration) private static readonly string db = ConfigurationManager.AppSettings["DB"]; //表示读取配置文件 public static IUser CreateUser() { string className = AssemblyName + "." + db + "User"; return (IUser)Assembly.Load(AssemblyName).CreateInstance(className); } public static IDepartment CreateDepartment() { string className = AssemblyName + "." + db + "Department"; return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className); } }}然后是各个相关类的代码:
class User { private int _id; public int ID { get { return _id; } set { _id = value; } } private string _name; public string Name { get { return _name; } set { _name = value; } } } class Department { private int _id; public int ID { get { return _id; } set { _id = value; } } private string _deptName; public string DeptName { get { return _deptName; } set { _deptName = value; } } } interface IUser { void Insert(User user); User GetUser(int id); } class SqlserverUser : IUser { public void Insert(User user) { Console.WriteLine("在Sqlserver中给User表增加一条记录"); } public User GetUser(int id) { Console.WriteLine("在Sqlserver中根据ID得到User表一条记录"); return null; } } class AccessUser : IUser { public void Insert(User user) { Console.WriteLine("在Access中给User表增加一条记录"); } public User GetUser(int id) { Console.WriteLine("在Access中根据ID得到User表一条记录"); return null; } } interface IDepartment { void Insert(Department department); Department GetDepartment(int id); } class SqlserverDepartment : IDepartment { public void Insert(Department department) { Console.WriteLine("在Sqlserver中给Department表增加一条记录"); } public Department GetDepartment(int id) { Console.WriteLine("在Sqlserver中根据ID得到Department表一条记录"); return null; } } class AccessDepartment : IDepartment { public void Insert(Department department) { Console.WriteLine("在Access中给Department表增加一条记录"); } public Department GetDepartment(int id) { Console.WriteLine("在Access中根据ID得到Department表一条记录"); return null; } }
User user = new User(); Department dept = new Department(); IUser iu = DataAccess.CreateUser(); //直接得到实际的数据库访问实例,而不存在任何依赖 iu.Insert(user); iu.GetUser(1); IDepartment id = DataAccess.CreateDepartment(); //直接得到实际的数据库访问实例,而不存在任何依赖 id.Insert(dept); id.GetDepartment(1); Console.Read();执行结果:
- 简单工厂、工厂方法与抽象工厂模式对比
- 简单工厂、工厂方法、抽象工厂模式
- 简单工厂、工厂方法、抽象工厂模式
- 简单工厂|工厂方法|抽象工厂模式
- 设计模式-简单工厂、工厂方法与抽象工厂
- 工厂三姐妹对比总结——简单工厂模式&工厂方法模式&抽象工厂模式
- 简单工厂、工厂方法与抽象工厂
- 【设计模式之四:工厂模式对比】简单工厂、工厂方法和抽象工厂的区别
- 工厂模式之简单工厂、工厂方法、抽象工厂分析对比
- 设计模式-工厂模式(简单工厂,工厂方法,抽象工厂)
- java工厂模式-简单工厂,工厂方法,抽象工厂模式
- 我看'工厂模式'--->"简单工厂、工厂方法、抽象工厂"
- 工厂模式(简单工厂,工厂方法,抽象工厂)
- 工厂模式(简单工厂+工厂方法+抽象工厂)
- 工厂模式(简单工厂、工厂方法、抽象工厂)
- 工厂模式(简单工厂、工厂方法、抽象工厂)
- 工厂模式详解(简单工厂+工厂方法+抽象工厂)
- 工厂模式详解(简单工厂+工厂方法+抽象工厂)
- keys可重复的字典
- 今天看到一篇介绍环形消息队列的文章,学习了
- MD5加密认证问题
- 自己动手写搜索引擎(常搜吧历程五#解析文档之XML#)(Java、Lucene、hadoop)
- uC/OS-II 学习笔记之:消息邮箱
- 简单工厂、工厂方法与抽象工厂模式对比
- 帮助你实现移动设备上的拖拽刷新功能的javascript类库 - hook.js
- control cleared invoice can't be cancelled
- http 简记
- 关于SQL Server的若干注意事项
- 选择是艰难的
- 4.1系统上平板开发需要注意的几个小问题
- itoa 和 atoi和字符串翻转等操作
- 关于AIDL调用的安全机制(存在2个AIDL的被调用方)