概念:
工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
解释说明:
1.在简单工厂中,客户端没有对具体产品有依赖,只是发出一个参数,工厂生产它要的结果。但是这样一来工厂就必须有逻辑判断,如果我们要扩展相应功能,那么工厂内部需要修改,新的功能也需要添加。这样的程序扩展性比较差,要加一些新功能的话,原先的代码也得改,这样不好。
2.在工厂方法中,我们可以直接添加各种功能,也就是各种具体的工厂,拓展性很好的。因为接口工厂部分不用动,通过这个统一的接口,我们实现出不同的具体工厂,然后用统一的方法在不同的工厂中实现不同的方法。
3.至于到底实现出哪个工厂,这个转为客户端来判断。因为判断早晚都得有,放在比较简单而且经常改动的客户端那部分还是可以接受的。
工厂方法实现:
接口工厂:
//定义工厂接口,使之后所有的具体工厂都可以用一个统一的方法实现不同的效果
interface IFactory
{
Operation CreateOperation();
}
具体工厂:
//这些不同的工厂类继承于接口工厂
//接口工厂的方法在这些类中返回不同的实例
class AddFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationAdd();
}
}
class SubFactory :IFactory
{
public Operation CreateOperation()
{
return new OperationSub ();
}
}
class MulFactory:IFactory
{
public Operation CreateOperation()
{
return new OperationMul ();
}
这些工厂实现了多态,而且可以不断扩展新的
具体运算:
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;
}
}
这些和之前的一样
static void Main(string[] args)
{
//获得用户输入值和符号
Console.Write("请输入数字A: ");
string strNumberA = Console.ReadLine();
Console.Write("请选择运算符号 (+ - * /):");
string strOperate = Console.ReadLine();
Console.Write("请输入数字 B: ");
string strNumberB = Console.ReadLine();
//声明一个工厂
IFactory operFactory=null;
//通过用户的符号参数来生成具体的工厂类
switch (strOperate)
{
case "+":
operFactory =new AddFactory();
break;
case "-":
operFactory =new SubFactory();
break;
case"*":
operFactory=new MulFactory();
break;
case "/":
operFactory = new DivFactory();
break;
}
//用同一个方法,在不同的工厂内实例化不同的方法
Operation oper = operFactory.CreateOperation();
oper.NumberA = Convert.ToDouble (strNumberA );
oper.NumberB = Convert.ToDouble (strNumberB );
double result = oper.GetResult();
Console.WriteLine("结果是:" + result);
Console.ReadLine();
}
}
感想:
还用上篇博客中吃水果的例子。
简单工厂是我(客户端)通过喊母亲(工厂),递给我不同的水果(根据要求实例化)。
但是随着我的胃口越来越大,想吃各种各样的水果,那么母亲就得买回一篮子一篮子各种不同的水果,而且她得和我们同步水果的名字,得学习认识新的水果。有一天,我们亲爱的母亲也烦了,我们的要求一变她就得学新的东西,而且还得买回来。终于母亲生气了,后果很严重。因为累了,时不时歇一歇,因为东西多,时不时弄错一些。
伟大的工厂方法是一个技术的转折。
我们知道母亲累了,所以母亲就做一件事情,执行一个动作就好了,帮我们去水果就好了。
那么水果哪里来?
当然是我们自己整了,不过是叫人弄。因为我们知道自己想吃什么,所以就自己点一种水果外卖送到家门口。世界上每出现一种新的水果生产者,我们就记一个电话(case语句),打个电话,具体的水果商开车到我家,我的妈妈每次都只是取水果,但是每次取得都不一样(完美实现了多态~)。
有了工厂方法,世界再次美好了,妈妈再也不用劳累了。
——本学习总结参考书籍为《大话设计模式》作者:程杰