引言和之前设计模式的总结
我们在学习每一个设计模式之前,应该都先知道我们所学的这个设计模式解决的问题,以及他的使用场景,比如我们最开始学的单例模式,解决客户端直接创建对象的问题,后来出现了这样那样的问题,我们使用了简单工厂设计模式,再使用了简单工厂设计模式之后,我们把根据对象来选择操作符进行了优化,将他写成一个类,类里面我们使用了静态方法。
之后我们又发现了新问题,简单工厂模式的缺点就是使用了的缺点就是破坏了我们的开闭原则。而且我们所有创建对象的逻辑都在方法里,一旦出现了问题,可能会导致我们整个程序的瓦解。所以基于此问题,我们学习了新的工厂方法设计模式,我们将创建对象抽成了类。将每个方法采用了继承父类的形式来创建对象。
之所以我们又抽象工厂设计模式,那就说明我们之前学的简单工厂设计模式或者是工厂方法设计模式依然存在问题。
创建不同品牌的键盘
简单工厂设计模式:
static void Main(string[] args)
{
}
//创建不通类型的键盘
public interface IKeyBorad
{
void ShowBord();
}
public class DellKeyBord:IKeyBorad
{
public void ShowBord()
{
Console.WriteLine("我是戴尔键盘!");
}
}
public class LenoveKeyBord : IKeyBorad
{
public void ShowBord()
{
Console.WriteLine("我是联想键盘!");
}
}
public class HPKeyBord : IKeyBorad
{
public void ShowBord()
{
Console.WriteLine("我是惠普键盘!");
}
}
public class KeyBordFactory
{
public static IKeyBorad GetIkeyBord(string bord)
{
IKeyBorad keyBorad = null;
switch (bord)
{
case "Dell":
keyBorad=new DellKeyBord();
break;
case "hp":
keyBorad = new HPKeyBord();
break;
case "lenovo":
keyBorad = new LenoveKeyBord();
break;
}
return keyBorad;
}
}
工厂方法设计模式:
static void Main(string[] args)
{
}
//创建不通类型的键盘
public interface IKeyBorad
{
void ShowBord();
}
public interface IKeyBordFactory
{
IKeyBorad GetKeyBorad();
}
public class DellFactroy : IKeyBordFactory
{
public IKeyBorad GetKeyBorad()
{
return new DellKeyBord();
}
}
public class HPFactroy : IKeyBordFactory
{
public IKeyBorad GetKeyBorad()
{
return new HPKeyBord();
}
}
public class LenovoFactroy : IKeyBordFactory
{
public IKeyBorad GetKeyBorad()
{
return new LenoveKeyBord();
}
}
public class DellKeyBord : IKeyBorad
{
public void ShowBord()
{
Console.WriteLine("我是戴尔键盘!");
}
}
public class LenoveKeyBord : IKeyBorad
{
public void ShowBord()
{
Console.WriteLine("我是联想键盘!");
}
}
public class HPKeyBord : IKeyBorad
{
public void ShowBord()
{
Console.WriteLine("我是惠普键盘!");
}
}
public class KeyBordFactory
{
public static IKeyBorad GetIkeyBord(string bord)
{
IKeyBorad keyBorad = null;
switch (bord)
{
case "Dell":
keyBorad = new DellKeyBord();
break;
case "hp":
keyBorad = new HPKeyBord();
break;
case "lenovo":
keyBorad = new LenoveKeyBord();
break;
}
return keyBorad;
}
}
随之而来的需求:我要添加鼠标、主机等其他产品
当我需要添加新的鼠标时,那我们的工厂方法模式就需要改了,我加一个产品,如果又三个牌子,那我就需要加三个工厂,如果有两个产品那我就需要加六个工厂。所以这就是我们工厂方法设计模式的问题。
抽象工厂设计模式来了
抽象工厂:就是为了缩减我们创建子类工厂的数量,没有必要给每一个产品分配一个工厂类。我们可以将产品分组。每组中的不同产品由每一个工厂类的不同方法来创建。下图是对这段话的实现
不难看出,如果我们使用工厂方法设计模式,那我们的最下面工厂就会有6个,但是,我们现在就是两个,大大的减少了我们的工厂的创建,这就是抽象工厂带给我们的好处,也就是有几个品牌就有几个工厂,我们在dell的工厂里生产鼠标、键盘等等
抽象工厂让我们的代码更简洁,不显得那么冗余
static void Main(string[] args)
{
//如果用户选择的是dell的
AbbtricFactrol abbtricFactrol=new DellFactrol();
IKeyBord keyBord = abbtricFactrol.GetKeyBord();
IMouseBord mouseBord = abbtricFactrol.GetMouseBord();
keyBord.ShowKeyBord();
mouseBord.ShowMouseBord();
//这里我们可以使用工厂方法设计模式里的反射获取对应关系
}
//鼠标 ,键盘
public interface IKeyBord
{
void ShowKeyBord();
}
public class DellKeyBord : IKeyBord
{
public void ShowKeyBord()
{
Console.WriteLine("我是戴尔类型的键盘");
}
}
public class HPKeyBord : IKeyBord
{
public void ShowKeyBord()
{
Console.WriteLine("我是惠普类型的键盘");
}
}
public class LenovoKeyBord : IKeyBord
{
public void ShowKeyBord()
{
Console.WriteLine("我是Lenovo类型的键盘");
}
}
public interface IMouseBord
{
void ShowMouseBord();
}
public class DellMouseBord : IMouseBord
{
public void ShowMouseBord()
{
Console.WriteLine("我是戴尔类型的鼠标");
}
}
public class HPMouseBord : IMouseBord
{
public void ShowMouseBord()
{
Console.WriteLine("我是惠普类型的鼠标");
}
}
public class LenovoMouseBord : IMouseBord
{
public void ShowMouseBord()
{
Console.WriteLine("我是Lenovo类型的键盘");
}
}
//创建工厂
public interface AbbtricFactrol
{
IKeyBord GetKeyBord();
IMouseBord GetMouseBord();
}
//这是戴尔工厂,未来所有和戴尔有关的设备都是在这里进行对象的创建
public class DellFactrol : AbbtricFactrol
{
public IKeyBord GetKeyBord()
{
return new DellKeyBord();
}
public IMouseBord GetMouseBord()
{
return new DellMouseBord();
}
}
//这是惠普工厂,未来所有和戴尔有关的设备都是在这里进行对象的创建
public class HPFactrol : AbbtricFactrol
{
public IKeyBord GetKeyBord()
{
return new HPKeyBord();
}
public IMouseBord GetMouseBord()
{
return new HPMouseBord();
}
}
//这是Lenovo工厂,未来所有和戴尔有关的设备都是在这里进行对象的创建
public class LenovoFactrol : AbbtricFactrol
{
public IKeyBord GetKeyBord()
{
return new LenovoKeyBord();
}
public IMouseBord GetMouseBord()
{
return new LenovoMouseBord();
}
}
在我们的抽象工厂设计模式中仍然有四个角色
- 抽象工厂角色:这是抽象工厂模式的核心。是具体的工厂角色必须诗函的接口或者必须继承的抽象类
- 具体工厂角色:包含了具体的业务逻辑相关的代码。由客户端来调用,创建对应的具体的产品对象
- 抽象产品角色:具体产品继承的父类或者接口
- 抽象产品角色:具体工厂角色创建的对象,也就是这个类的实例
抽象工厂就是将相同类型的进行分类,减少我们的工厂。
总结
简单工厂模式:一个工厂类,一个抽象类,若干个子类,工厂类创建方法依据传入参数并且判断。选择创建具体的产品对象
工厂方法模式:多个工厂类,利用多态创建不同的产品对象。
抽象工厂:多个工厂类,多个抽象类,若干产品子类分组。减少了工厂子类的数量