设计模式中的三工厂指简单工厂模式、工厂方法模式、抽象工厂模式。
我们来逐步比较这三个模式的区别:
简单工厂模式核心代码:
<span style="font-size:18px;">//简单运算工厂类</span>
<span style="font-size:18px;">Public class OperationFactoty
{
Public static Operation createOperate(stirng operate)
{
Operation oper = null;
Switch(operate) //通过Switch实例化出合适的对象
{
Case “+”
Oper = new OperationAdd();
Break;
Case”-”
Oper=new OperationSub();
Break;
Case”*”
Oper= new OperationSub();
Break;
Case”\”
Oper= new OperationDiv();
Break;
}
Return oper;
}
}
客户端代码:
Opeaton oper;
Oper = OperationFactory.createOperate(“+”); //输入"+",实例化出加法对象
Oper.NumberA=1;
Oper.NumberB=2;
Double result = oper.Getresult();
</span>
优点:工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态的实例化相关的类,对客户端来说,去除了与具体产品的依赖。
缺点:如果要增加新的功能,需要在运算工厂类里加case,违背了开放—封闭原则。
由此可见,我们只要在客户端输入相应的符号,我们的工厂就能实例化出合适的对象,如:我们的代码实例化出加法对象。
在简单工厂模式的基础上我们再来看工厂方法模式,其核心代码如下:
<span style="font-size:18px;">//构建工厂接口</span>
<span style="font-size:18px;">Interface IFactory
{
Operation CreateOperation();
}
</span>
<span style="font-size:18px;">//构建具体工厂去实现这个接口
Class Addfactoty : IFactoty
{
Public Operation CreateOperation()
{
Return new OperationAdd();
}
}
Class SubFactoty : IFactoty
{
Public Operation CreateOperation()
{
Return new OperationSub();
}
}
Class MulFactoty : Ifactoty
{
Public Operation CreateOperation()
{
Return new OperationMul();
}
}
Class DivFactoty : IFactory
{
Public Operation createOperation();
{
Return new OperationDiv();
}
}
客户端代码:
IFactoty operFactoty = new AddFactoty(); //实例化出加法工厂
Operation oper= operFactoty.CreateOperation();
Oper.NumberA =1;
Oper.NumberB=2;
Double result = oper.GetResult();
</span>
工厂方法模式是对简单工厂模式违背开放——封闭原则的改进。
工厂方法模式把工厂类抽象出一个接口,所有的要生产具体类的工厂去实现这个接口。
优点:一个简单模式的工厂类,变成 了一个工厂抽象接口和多个具体生成对象的工厂,我们要增加功能时不需要再更改原有的工厂类,只需增加此功能的运算类和相应的工厂类。
在工厂方法模式的基础上我们再来看抽象工厂模式:
<span style="font-size:18px;">//IDepartment接口,用于客户端访问,解除与具体数据库访问的耦合</span>
<span style="font-size:18px;">Interface IDepartment
{
Void Insert (Department department);
Department GetDepartment (int id);
}</span>
<span style="font-size:18px;">
</span>
<span style="font-size:18px;">//SqlserverDepartment类,用于访问SQL Server的Department
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;
}
}</span>
<span style="font-size:18px;">
</span>
<span style="font-size:18px;"></span><pre name="code" class="csharp"><span style="font-size:18px;">//AccessDepartment</span><span style="font-size: 18px; font-family: Arial, Helvetica, sans-serif;">类,用于访问Access的Department</span>
<pre name="code" class="csharp">Class AccessDepartment:IDepartment
{
Public void Insert(Department department)
{
Console.WriteLine(“在Access中给Department表增加一条记录”);
}
Public Department GetDepartment(int id)
{
Console.WriteLine(“在Access中根据ID得到Department表一条记录”);
Return null;
}
}
<span style="font-size:18px;">
</span>
<span style="font-size:18px;">//IFactoty接口,定义一个创建访问Department表对象的抽象工厂接口
Interface IFactoty
{
IUser CreateUser();
IDepartment CreateDepartment();
}
</span>
<span style="font-size:18px;"></span><pre name="code" class="csharp"><span style="font-size: 18px;">//SqlServerFactory类,实现IFactoty接口,实例化出SqlserverUser和SqlserverDepartment</span>
<span style="font-size:18px;">Class SqlServerFactory: IFactoty
{
Public IUser CreateUser()
{
Return new SqlserverUser();
}
Public IDepartment CreateDepartment()
{
Return new SqlserverDepartment();
}
}</span>
<span style="font-size:18px;">
</span>
<span style="font-size:18px;">//AccessFactoty类,实现IFactoty接口,实例化出AccessUser和AccessDepartment
Class AccessFactoty: IFactoty
{
Public IUser CreateUser()
{
Return new AccessUser()
}
Public IDepartment CreateDepartment()
{
Return new AccessDepartment ();
}
}
客户端代码
Static void
Main(string [] args)
{
User user = new User();
Department dept = new Department();</span>
<span style="font-size:18px;"><span style="white-space:pre"> </span> //IFactory factoty =new SqlServerFactory();,确定实例化出哪个对象给factory
IFactoty factory = new AccessFactoty();
</span><h1><span style="font-size:18px;"> IUser iu = factory.CreateUser();</span></h1><span style="font-size:18px;"> iu.Insert(user);
iu.GetUser(1);
IDepartment id=factory.CreateDepartment();
id.Insert(dept);
id.GetDepartment(1);
console.read();
}
</span>
由以上代码我们可以看出当有一个工厂类,和工厂操作类的时候,我们要用工厂方法模式。
那么什么情况下用抽象工厂模式呢?
现在我们代码中所写的是给User类又增加一个Department类的结果,所以我们可以得出结论:当涉及到多个产品系列问题时,如代码中SQL Server与Access是两个不同分类,而这两个分类都涉及到User类和Department类,这时我们就可以使用抽象工厂类。
简单工厂模式、工厂方法模式、抽象工厂模式之间是有递进关系的,能解决的问题由简到繁,逻辑上也相对复杂一点,把这三个放到一起去看,联系很紧密,差别也很明显。