1. 简单工厂的实现
B: 这个和简单工厂有什么区别,感觉还不如简单工厂方便,为什么要用这个模式,到底这个模式的精髓在哪里?
简单工厂模式结构图:
工厂类的代码:
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;
}
}
}
}
客户端:
Operation oper;
oper = OperationFactory.createOperate("+");
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();
2. 工厂方法模式实现
工厂方法结构图:
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; }
}
/// <summary>
/// 得到运算结果
/// </summary>
/// <returns></returns>
public virtual double GetResult()
{
double result = 0;
return result;
}
}
/// <summary>
/// 加法类
/// </summary>
class OperationAdd : Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA + NumberB;
return result;
}
}
/// <summary>
/// 减法类
/// </summary>
class OperationSub : Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA - NumberB;
return result;
}
}
/// <summary>
/// 乘法类
/// </summary>
class OperationMul : Operation
{
public override double GetResult()
{
double result = 0;
result = NumberA * NumberB;
return result;
}
}
/// <summary>
/// 除法类
/// </summary>
class OperationDiv : Operation
{
public override double GetResult()
{
double result = 0;
if (NumberB == 0)
throw new Exception("除数不能为0。");
result = NumberA / NumberB;
return result;
}
}
/// <summary>
/// 工厂方法
/// </summary>
interface IFactory
{
Operation CreateOperation();
}
/// <summary>
/// 专门负责生产“+”的工厂
/// </summary>
class AddFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationAdd();
}
}
/// <summary>
/// 专门负责生产“-”的工厂
/// </summary>
class SubFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationSub();
}
}
/// <summary>
/// 专门负责生产“*”的工厂
/// </summary>
class MulFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationMul();
}
}
/// <summary>
/// 专门负责生产“/”的工厂
/// </summary>
class DivFactory : IFactory
{
public Operation CreateOperation()
{
return new OperationDiv();
}
}
客服端:
class Program
{
static void Main(string[] args)
{
IFactory operFactory = new AddFactory();
Operation oper = operFactory.CreateOperation();
oper.NumberA = 1;
oper.NumberB = 2;
double result=oper.GetResult();
Console.WriteLine(result);
Console.Read();
}
}
3. 简单工厂vs.工厂方法
B: 增加其他运算,例如M数的N次方,这些功能的增加,在简单工厂里,我是先去加'求M数的N次方'功能类,然后去更改工厂方法,当中加入'Case'语句来做判断,现在用来工厂方法,加功能类没有问题,再加相关的工厂类,这也没问题,但要我再去改客服端,这不等于不但没有减低难度,反而增加了很多类和方法,把复杂性提高了?
A: 简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客服端的选择条件动态的实例化相关的类,对于客服端来说,去除了与具体产品的依赖。但问题也就在这里,如你所说,增加运算类,我们是一定需要给运算工厂类的方法里加'Case'的分支条件,修改原有的类?这等于说,我们不但对于扩展开放,对于修改也开放,这就背叛了开放-封闭原则。工厂方法就是为了解决这个。
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法模式结构图:
A:既然这个工厂类与分支耦合,那么我就对它下手,根据依赖倒转原则,我们把工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的工厂方法。然后,所有的要生产具体产品类的工厂,就去实现这个接口,这样,一个简单工厂模式的工厂类,变成了一个工厂抽象接口和多个具体生成对象的工厂,于是增加运算类时,就不需要更改原有的工厂类了,只需要增加此功能的运算类和相应的工厂类就可以了。
A: 工厂方法模式实现时,客服端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑移到了客服端代码来进行。你想要加功能,本来是改工厂类,而现在是修改客服端。
4. 雷锋工厂
B: 老人不需要知道是谁来做好事,他只需知道是学雷锋的人来帮忙就可以了。
class Program
{
static void Main(string[] args)
{
//
//基本方式:薛磊风代表大学生学习雷锋
LeiFeng xueleifeng = new Undergraduate();
xueleifeng.BuyRice();
xueleifeng.Sweep();
xueleifeng.Wash();
LeiFeng student1 = new Undergraduate();
student1.BuyRice();
LeiFeng student2 = new Undergraduate();
student2.Sweep();
LeiFeng student3 = new Undergraduate();
student3.Wash();
//简单工厂模式
LeiFeng studentA = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
studentA.BuyRice();
LeiFeng studentB = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
studentB.Sweep();
LeiFeng studentC = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
studentC.Wash();
//工厂方法模式
IFactory factory = new UndergraduateFactory();
LeiFeng student = factory.CreateLeiFeng();
student.BuyRice();
student.Sweep();
student.Wash();
Console.Read();
}
}
//雷锋
class LeiFeng
{
public void Sweep()
{
Console.WriteLine("扫地");
}
public void Wash()
{
Console.WriteLine("洗衣");
}
public void BuyRice()
{
Console.WriteLine("买米");
}
}
//学雷锋的大学生
class Undergraduate : LeiFeng
{ }
//社区志愿者
class Volunteer : LeiFeng
{ }
//简单雷锋工厂
class SimpleFactory
{
public static LeiFeng CreateLeiFeng(string type)
{
LeiFeng result = null;
switch (type)
{
case "学雷锋的大学生":
result = new Undergraduate();
break;
case "社区志愿者":
result = new Volunteer();
break;
}
return result;
}
}
//雷锋工厂
interface IFactory
{
LeiFeng CreateLeiFeng();
}
//学雷锋的大学生工厂
class UndergraduateFactory : IFactory
{
public LeiFeng CreateLeiFeng()
{
return new Undergraduate();
}
}
//社区志愿者工厂
class VolunteerFactory : IFactory
{
public LeiFeng CreateLeiFeng()
{
return new Volunteer();
}
}
A: 简单工厂实例化是要3遍,而工厂模式只需一次。
B: 我觉得工厂方法克服了简单工厂违背开放-封闭原则,又保持了封装对象创建过程的优点。
A: 由于使用了多态性,工厂方法模式保持了简单工厂的优点,而且克服了它的缺点。但是缺点是由于每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。
A: 利用'反射'可以解决避免分支判断的问题。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。