工厂模式
工厂模式分为3种,简单工厂,工厂方法模式,抽象工厂模式
目的都是为了解决客户端在使用类的时候强耦合性。
简单工厂模式
简单工厂模式是最简单的工厂模式,里面只用关注工厂就行了,工厂里面加工所有一类东西,通过流式选择选择加工的东西
我们以水果作为例子进行记录
工厂:
/// <summary>
/// 生产水果,但是不让外界知道细节
/// </summary>
class SimplyFactory
{
public Fruit CreatFruit(string name)
{
switch (name)
{
case "apple":return new Apple(name);
case "pear": return new Pear(name);
default:return new Otherfruits();
}
}
}
生产对象:apple和pear
class Apple:Fruit
{
public Apple(string Name)
{
this.Name = Name;
}
public string Name { get; set; }
}
class Pear:Fruit
{
public Pear(string Name)
{
this.Name = Name;
}
public string Name { get; set; }
}
使用者:
public void eat() {
Fruit apple = new SimplyFactory().CreatFruit("apple");
Fruit pear = new SimplyFactory().CreatFruit("pear");
Console.WriteLine(apple.Name);
Console.WriteLine(pear.Name);
}
这里使用简单工厂不仅只限于解耦合,而且在使用中对生产的apple或者pear有要求时,只需要修改工厂就好了,不用像直接调用那样,每个调用的地方都要修改。
这就是简单工厂模式,但是在应用中会发现简单工厂模式的不足。
- 就是对于扩展来说,我们需要修改工厂的内部,我们违反开闭原则
- 工厂中不能责任单一,我们违反了责任单一原则
所以需要对这个简单工厂模式修改,要保证上面原则的实现,如何修改能保证开闭原则和责任单一原则?
我们需要针对这个工程进行分析开闭原则,可以将工厂分开,让apple工厂和pear工厂...等等分开,这样不就实现了开闭原则,仔细想下同时实现
了责任单一原则。
将工厂分开就是所谓的工厂方法模式
apple:
class AppleFactory
{
public Fruit creatFruit(string name)
{
return new Apple(name);
}
}
pear:
class PearFactory
{
public Fruit creatFruit(string name)
{
return new Pear(name);
}
}
class User
{
public void eat()
{
Fruit apple = new AppleFactory().creatFruit("apple");
Fruit pear = new PearFactory().creatFruit("pear");
Console.WriteLine(apple + "---"+pear);
}
}
分析下上面的工厂方法模式,发现这个写法好像耦合性不仅没有降低而且耦合中还夹杂了工厂,感觉不如直接调用简单,这个感觉是没错的,因为工厂
的规模比较小,如果生产是个复杂的系统,才能体现出他的优势。
分析下现在的开闭原则和责任单一原则
- 符合开闭原则,因为他在扩展桃、杏等水果时,不需要再对工厂进行修改了,值用增加新的子类工厂就好了
- 符合责任单一原则,因为每个工厂只负责本身事件的生产。
工厂方法模式的问题是将实例类型交给了客户端,这样就需要对这个类型进行抽象(我的代码式样不能展示出抽象
的好处,试想下一个场景,在传递的过程中我能将传参里面写了具体的工厂类AppleFactory或者写了抽象的工厂类
AbstractMethodFactory这两个区别,后面的在项目的迭代过程中更有优势,因为项目迭代过程中能保证你传递参数
类的开闭原则,并且减少你代码修改,提高系统的健壮性)
抽象工厂模式
将工厂抽象化在实现就是所谓的抽象工厂模式
抽象工厂:
/// <summary>
/// 建立抽象工厂
/// </summary>
abstract class AbstractMethodFactory
{
abstract public Fruit CreatFruit(string name);
}
apple工厂:
class AppleFactory : AbstractMethodFactory
{
public override Fruit CreatFruit(string name)
{
return new Apple(name);
}
}
pear工厂:
class PearFactory : AbstractMethodFactory
{
public override Fruit CreatFruit(string name)
{
return new Pear(name);
}
}
使用者:
class User
{
public void eat()
{
Fruit apple = new AppleFactory().CreatFruit("apple");
Console.WriteLine(apple.Name);
Fruit pear = new PearFactory().CreatFruit("pear");
Console.WriteLine(pear.Name);
}
}
抽闲工厂模式很好的实现了依赖倒置原则,细节依赖于抽象,会将细节隐藏到抽象下,并且实体工厂时很方便
但是缺点也比较明显。如果工厂有其他的产品增加,就需要增加抽象里的抽象方法,并且之前的工厂子类也要修改
(这里使用的是抽象可以不用去修改子类),这里我写的不规范这里应该使用interface,修改了就违反了开闭原则,并且在扩展后
需要将之前的子类都要添加这个方法,所以这个抽象工厂模式适合稳定的生产线(不增加产品功能,只增加产品的类型)。