在工厂模式家族中最出名的是工厂三姐妹,根据抽象的程度不同分为简单工厂、工厂模式和抽象工厂模式。他们在我们平时的编程中会经常使用。所以我们应该详细地了解一下他们三者之间优缺点。
简单工厂
定义
简单工厂模式又叫做静态工厂方法(Static FactoryMethod)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
举例说明:
代码实现:
代码语言:javascript复制<span style="font-size:18px;">//客户端代码
static void Main(string[] args)
{
Operation oper;
oper = OperationFactory.createOperate("*");
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();
}
}
//Operation运算类
public class Operation
{
private double _numberA = 0;
private double _numberB = 0;
public double NumberA
{
get { return _numberA; }
set { _numberA = value; }
}
public double NumberB
{
get { return _numberB; }
set { _numberB = value; }
}
public virtual double GetResult()
{
double result = 0;
return result;
}
}
//加减乘除类
class OperationAdd : Operation //加法类,继承运算类
{
public override double GetResult()
{
double result = 0;
result = NumberA NumberB;
return result;
}
}
class OperationSub : Operation //减法类,继承运算类
{
public override double GetResult()
{
double result = 0;
result = NumberA - NumberB;
return result;
}
}
class OperationMul : Operation //乘法类,继承运算类
{
public override double GetResult()
{
double result = 0;
result = NumberA * NumberB;
return result;
}
}
class OperationDiv : Operation //除法类,继承运算类
{
public override double GetResult()
{
double result = 0;
if (NumberB == 0)
throw new Exception("除数不能为0。");
result = NumberA / NumberB;
return result;
}
}
//简单运算工厂类
class OperationFactory
{
public static Operation createOperate(string operate)
{
Operation oper = null;
switch (operate)
{
case " ":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
}
return oper;
}
}</span>
简单工厂的优点:
1、工厂类是整个模式的关键.包含了必要的逻辑判断,根据给定的信息,决定究竟应该创建哪个具体类的实例。
2、明确了各自的职责和权利,有利于整个软件体系结构的优化。
简单工厂的缺点:
1、由于工厂类集中了所有实例的创建逻辑,违反了高内聚低耦合原则,将全部创建逻辑集中到了一个工厂类中;
2、它所能创建的类只能是事先考虑到的,每次扩展都需要更改工厂类,违反了开放封闭原则。
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类的实例。
工厂模式
定义:
用于创建对象的接口,让子类决定实例化哪一个类。工厂模式对类的实例化延迟到其子类。
举例说明:数据访问程序
代码实现:
代码语言:javascript复制<span style="font-size:18px;"> static void Main(string[] args)
{
User user = new User();
IFactory factory = new SqlServerFactory();
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);
Console.Read();
}
}
//User类
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 ;}
}
}
//IUser接口
interface IUser
{
void Insert(User user);
User GetUser(int id);
}
//SqlserverUser类
class SqlserverUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在SQL Server 中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在SQL Server 中根据ID得到User表一条记录");
return null;
}
}
//AccessUser类
class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("在Access中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine("在Access中根据ID得到User表一条记录");
return null;
}
}
//IFactory接口
interface IFactory
{
IUser CreateUser();
}
//SqlServerFactory :IFactory
class SqlServerFactory : IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
}
//AccessFactory类
class AccessFactory:IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
}</span>
工厂模式的优点:
1、克服了简单工厂违背开放封闭原则的缺点,保持了封装的优点。工厂模式集中封装了对象的创建,更换对象时更加容易。 2、使用了多态性,保持了简单工厂的优点。 3、降低耦合度。降低了客户程序与产品对象的耦合。
抽象工厂
定义:
创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
举例说明:数据访问程序
代码实现:
代码语言:javascript复制<span style="font-size:18px;"> static 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);
Console.Read();
}
}
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 ;}
}
}
//IUser接口
interface IUser
{
void Insert(User user);
User GetUser(int id);
}
// IUser接口的子SqlserverUser类,用于访问SQL Server的User
class SqlserverUser :IUser
{
public void Insert(User user)
{
Console.WriteLine("在SQL Server中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine ("在SQL Server中根据ID得到User表一条记录");
return null;
}
}
// IUser接口的子AccessUser类,用于访问Access的User
class AccessUser :IUser
{
public void Insert(User user)
{
Console.WriteLine ("在Access中给User表增加一条记录");
}
public User GetUser(int id)
{
Console.WriteLine ("在Access中根据ID得到User表中一条记录");
return null;
}
}
//增加一个Department表
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; }
}
}
//IDpartment接口
interface IDepartment
{
void Insert(Department department);
Department GetDepartment(int id);
}
//sqlserverDepartment类
class SqlserverDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在SQL Server中给Department表增加一条记录");
}
public Department GetDepartment(int id)
{
Console.WriteLine("在SQL Server中根据ID得到Department表一条记录");
return null;
}
}
//AccessDepartment类
class AccessDepartment : IDepartment
{
public void Insert(Department department)
{
Console.WriteLine("在Access中给Departmen表增加一条记录");
}
public Department GetDepartment(int id)
{
Console.WriteLine("在Access中根据ID得到Departmen表一条记录");
return null;
}
}
//抽象工厂的接口
interface IFactory
{
IUser CreateUser();
IDepartment CreateDepartment(); //增加的接口方法
}
class SqlServerFactory : IFactory
{
public IUser CreateUser()
{
return new SqlserverUser();
}
public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
}
class AccessFactory : IFactory
{
public IUser CreateUser()
{
return new AccessUser();
}
public IDepartment CreateDepartment()
{
return new AccessDepartment();
}
}</span>
抽象工厂的优点:
抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部创建不同的产品对象。
抽象工厂的缺点:
对于增加需求,扩展程序时,需要增加许多子类,使得程序变得臃肿,麻烦。(此时可以利用放射 抽象工厂的方法避免)。
总结:
无论是简单工厂模式,工厂模式,还是抽象工厂模式,他们都属于工厂模式,并且是创建型模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。