概括:在我们日常生活中,每天都会烧开水和烧菜,那么,烧开水就相当于一个简单的new操作,构造的对象就是白开水。而烧菜就相当于一个复杂的new操作,构造的对象就是菜肴。那我们如何才能轻松地得到想吃的菜肴,而不必关心烧菜的过程尼?
答案当然是去饭店点菜了,这样你只需要提供菜名就OK了,实现这种需求所用到的设计模式就是工厂模式。
分类:
简单工厂模式:一个饭店,可以提供酸辣土豆丝,红烧鱼,各种菜肴,比如菜馆。
工厂方法模式:多个饭店,每个饭店只能做一种菜肴,比如火锅店,面馆。
抽象工厂模式:这里不对抽象工厂模式做出解释,因为对于初学设计模式的同学来说,它和工厂方法模式容易一起理解容易晕掉,它只是工厂方法模式的一个简单变形,根据项目实际需求的变化而变化。
常规模式
UML图
代码实现:
public class Potato1
{
public Potato1()
{
Console.WriteLine("酸辣土豆丝");
}
}
public class Fish1
{
public Fish1()
{
Console.WriteLine("红烧鱼");
}
}
public class People1
{
Potato1 potato = new Potato1();
Fish1 fish = new Fish1();
}
显然,常规模式下的代码,耦合性太高,所以我们需要创建一个饭店类,来为我们完成烹饪的过程,即简单工厂模式。
简单工厂模式
UML图
代码实现:
public enum FoodsType
{
None,
Potato,
Fish
}
public abstract class Foods
{
public Foods()
{
}
}
public class Potato2 : Foods
{
public Potato2()
{
Console.WriteLine("酸辣土豆丝");
}
}
public class Fish2 : Foods
{
public Fish2()
{
Console.WriteLine("红烧鱼");
}
}
public class Restaurant
{
public static Foods Cook(FoodsType type)
{
switch (type)
{
case FoodsType.Potato:
return new Potato2();
case FoodsType.Fish:
return new Fish2();
default:
return null;
}
}
}
public class People2
{
Foods potato = Restaurant.Cook(FoodsType.Potato);
Foods fish = Restaurant.Cook(FoodsType.Fish);
}
显然,每增加一种新菜,都要在饭店类中增加相应的创建业务逻辑(Cook(FoodsType type)方法需要新增case),这显然是违背开闭原则的,那么我们将工厂类定义成了接口,而每种新增的菜肴,就增加该菜肴对应的饭店类,这样饭店的设计就可以扩展了,而不必去修改原来的代码,这就是工厂方法模式。
工厂方法模式
UML图
代码实现:
public abstract class Foods
{
public Foods()
{
}
}
public class Noodle : Foods
{
public Noodle()
{
Console.WriteLine("面条");
}
}
public class HotPot : Foods
{
public HotPot()
{
Console.WriteLine("火锅");
}
}
interface Restaurant
{
Foods Cook();
}
public class NoodleRestaurant : Restaurant
{
public override Foods Cook()
{
return new Noodle();
}
}
public class HotPotRestaurant : Restaurant
{
public override Foods Cook()
{
return new HotPot();
}
}
public class People
{
public static void main(String[] args)
{
NoodleRestaurant noodleRestaurant = new NoodleRestaurant();
Foods noodle = noodleRestaurant.Cook();
HotPotRestaurant hotPotRestaurant = new HotPotRestaurant();
Foods hotPot= hotPotRestaurant.Cook();
}
}