设计模式之 – 工厂模式:
工厂方法模式 (factory method): 定义一个用于创建对象的接口,让子类决定实例化那一个类。工厂方法使一个类的实例化延迟到其子类。
结构图:
工厂方法模式的实现 比简单工厂模式更进一步实现了依赖倒转原则,把工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的方法。然后所有要生产具体类的工厂,就去实现这个接口。这样,一个简单工厂模式的工厂类,变成了一个工厂抽象接口和多个具体生产对象的工厂。于是,我们要增加其他功能时,就不需要更改原有的工厂类了,只需怎加需要的功能类和相应的工厂类就可以了。
代码实现:
运算基类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式
{
public class Operation
{
public double Num1 { get; set; }
public double Num2 { get; set; }
public Operation()
{
}
public Operation(double n1,double n2)
{
this.Num1 = n1;
this.Num2 = n2;
}
/// <summary>
/// 普通运算
/// </summary>
/// <returns></returns>
public virtual double GetResult()
{
return 0;
}
/// <summary>
/// 平方运算
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
public virtual double Square(double n)
{
return 0;
}
/// <summary>
/// 开平方运算
/// </summary>
/// <returns></returns>
public virtual double Sqrt()
{
return 0;
}
/// <summary>
/// 以10为底的对数运算
/// </summary>
/// <returns></returns>
public virtual double Logarithm10()
{
return 0;
}
}
}
加减乘除运算子类,这里演示只有加法类重写了其他运算方法 :
/// <summary>
/// 减法类
/// </summary>
class SubOperation : Operation
{
public SubOperation(double n1,double n2):base(n1,n2)
{
}
public SubOperation()
{
}
public override double GetResult()
{
return Num1 - Num2;
}
}
/// <summary>
/// 乘法类
/// </summary>
public class MulOperation : Operation
{
public MulOperation(double n1, double n2) : base(n1, n2)
{
}
public MulOperation()
{
}
public override double GetResult()
{
return Num1 * Num2;
}
}
/// <summary>
/// 除法类
/// </summary>
class DivisionOperation : Operation
{
public DivisionOperation(double n1,double n2):base(n1,n2)
{
}
public DivisionOperation()
{
}
public override double GetResult()
{
if(Num1==0||Num2==0)
{
Console.WriteLine("除数和被除数不能为0");
return 0;
}
return Num1 / Num2;
}
}
/// <summary>
/// 加法类
/// </summary>
public class AddOperation : Operation
{
public AddOperation()
{
}
public AddOperation(double n1, double n2) : base(n1, n2)
{
}
public override double GetResult()
{
return Num1 + Num2;
}
public override double Square(double n)
{
return Math.Pow(Num1,n) + Math.Pow(Num2,n);
}
public override double Sqrt()
{
return Math.Sqrt(Num1) + Math.Sqrt(Num2);
}
public override double Logarithm10()
{
return Math.Log10(Num1) + Math.Log10(Num2);
}
}
抽象工厂和各个功能工厂类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 工厂模式.Factory
{
/// <summary>
/// 抽象工厂
/// </summary>
public interface IFactory
{
Operation CreateOperation();
Operation CreateOperation(double n1,double n2);
}
}
namespace 工厂模式.Factory
{
/// <summary>
/// 加法工厂类
/// </summary>
public class AddOperationFactory : IFactory
{
public Operation CreateOperation()
{
return new AddOperation();
}
public Operation CreateOperation(double n1, double n2)
{
return new AddOperation(n1,n2);
}
}
}
namespace 工厂模式.Factory
{
/// <summary>
/// 减法工厂
/// </summary>
public class SubOperationFactory : IFactory
{
public Operation CreateOperation() => new SubOperation();
public Operation CreateOperation(double n1, double n2) => new SubOperation(n1, n2);
}
}
namespace 工厂模式.Factory
{
/// <summary>
/// 乘法工厂
/// </summary>
public class MulOperationFactory : IFactory
{
public Operation CreateOperation()
{
return new MulOperation();
}
public Operation CreateOperation(double n1, double n2)
{
return new MulOperation(n1,n2);
}
}
}
namespace 工厂模式.Factory
{
/// <summary>
/// 除法工厂
/// </summary>
public class DivisionOperationfactory : IFactory
{
public Operation CreateOperation()
{
return new DivisionOperation();
}
public Operation CreateOperation(double n1, double n2)
{
return new DivisionOperation(n1,n2);
}
}
}
客户端调用:
class Program
{
static void Main(string[] args)
{
//加法工厂
IFactory factory = new AddOperationFactory();
//加法运算类
Operation op = factory.CreateOperation(3, 4);
//求平方和运算
double d= op.Square(2);
Console.WriteLine(d);
Console.ReadKey();
}
}
程序结构图:
工厂方法模式的实现时,客户端需要决定实例化那一个工厂来实现运算类,选择判断的问题还是存在,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。你想要增加功能,本来是修改工厂类,现在是修改客户端。但是修改代码数量大大降低,只需修改一行工厂类实现( IFactory factory = new AddOperationFactory();)就可以实现转换。
工厂方法模式克服了简单工厂违背 开放 – 封闭原则的缺点。有保持了封装对象创建的过程的优点。降低了客户端程序与产品对象的耦合,工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法保持了简单工厂的优点,而且克服了它的缺点。但缺点是,每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。