简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
工厂方法:Factory Method, 定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。你想要的加功能,本来是改工厂类的,而现在是修改客户端。
工厂方法模式是简单工厂模式的进一步抽象和推广,由于使用了多态性,工厂方法保持了简单工厂模式的优点。而且客服了它的缺点。但缺点是由于每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。
学雷锋:简单工厂模式 vs 工厂方法模式
using System;
using System.Collections.Generic;
using System.Text;
namespace 工厂方法_雷锋工厂
{
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();
}
}
#region 简单工厂模式
//雷锋
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;
}
}
#endregion
#region 工厂方法模式
//雷锋工厂
interface IFactory
{
LeiFeng CreateLeiFeng();
}
//学雷锋的大学生工厂
class UndergraduateFactory : IFactory
{
public LeiFeng CreateLeiFeng()
{
return new Undergraduate();
}
}
//社区志愿者工厂
class VolunteerFactory : IFactory
{
public LeiFeng CreateLeiFeng()
{
return new Volunteer();
}
}
#endregion
}
计算器-- 工厂方法模式
using System;
using System.Collections.Generic;
using System.Text;
namespace 工厂方法_计算器
{
/// <summary>
/// 运算类
/// </summary>
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();
}
}
}
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();
}