抽象工厂模式
目录
1.基础
抽象工厂模式->创建型设计模式
定义:提供一个接口,可以创建一系列相关或相互依赖的对象,而无需指定它们具体的类。(理解:利用抽象工厂模式,产生一个类似模板的抽象类,例如A,规定A的主要需求(例如A需要获得某某产品,但并不知道所需的产品是怎么生产出来的),剩下的让其他具体实现类继承该类,根据规定自己生产)
优点:
1.具体产品在应用层的代码隔离(创建一个大致的目标而不必纠结其实现的细节);
1.将一个系列的产品统一到一起创建,实现扩展性很强;
2.降低程序耦合度,减少重复代码产生;
缺点:
1.规定了所有可能被创建的产品集合,产品族中扩展新的产品困难;(例如下面实现中,若抽象类工厂增加其他创建设备的方法,则几乎所有的工厂类都需要进行修改->要求所有具体的工厂也可以提供该设备,详情请看下面案例)
2.增加了系统的抽象性和理解难度;
抽象工厂结构图
其中Factory为工厂的抽象角色,而Factory1和Fatcory2是负责生产的具体的工厂角色。ProductA、ProductB扮演两种产品的抽象角色,而ProductA1、ProductA2则扮演的是具体的产品角色,是被具体的工厂进行生产的。
抽象类和接口
相似之处:
1.皆不能实例化;
2.包含未实现的方法声明;
3.派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);
区别:
1.抽象类用abstract关键字,接口为interface关键字;
2.接口命名规范为第一个字母是大写I;
3.抽象类里的抽象方法要用abstract修饰,接口里面访问修饰符无意义;
4.抽象类里的普通方法可以有实现(方法有方法体),接口只能定义方法(的签名),不能有方法的实现;
5.接口是用来限制一个类的行为的;
6.一个类一次可以实现若干个接口,但是只能扩展一个父类;
...
2.实现
C#控制台程序
- 理解
An手机工厂需要三个设备Camera、Screen和Battery,已有两个具体工厂Sony、Samsung,利用抽象工厂模式实现其获取。
创建AnPhoneFactory抽象类,编写所需的创建设备的抽象方法,以获取所需的设备(这里不必关心设备来自于什么具体工厂)。创建Camera、Screen和Battery抽象类规定An工厂所需的设备数据。在Sony、Samsung工厂类中继承AnPhoneFactory,即皆要可以返回An手机工厂需要的所有设备。接下来,由具体工厂各自实现设备生产,继承An手机工厂规定的Camera、Screen和Battery抽象类,返回An手机工厂所需的所有设备数据。
- 代码
namespace ConsoleApp1 { public class Prpgram { static void Main(String[] args) { Console.WriteLine("An手机发布会:"); AnPhoneFactory anPhoneFactory_sony = new SonyFactory(); //设置设备为sony工厂提供 Camera camera = anPhoneFactory_sony.CreateCamera(); //通过Sony设备规格生产摄像头 camera.Pixel(); //打印Sony牌摄像头设备的像素信息 camera.LensSize(); //打印Sony牌摄像头设备的镜头大小信息 Screen screen = anPhoneFactory_sony.CreateScreen(); //通过Sony设备规格生产屏幕 screen.Resolution(); screen.ScreenMaterial(); Battery battery = anPhoneFactory_sony.CreateBattery(); battery.BatteryCapacity(); battery.StandardVoltage(); Console.WriteLine("An手机发布会:"); AnPhoneFactory anPhoneFactory_sam = new SamsungFactory(); //设置设备为Samsung工厂提供 Camera camera1 = anPhoneFactory_sam.CreateCamera(); camera1.Pixel(); camera1.LensSize(); Screen screen1 = anPhoneFactory_sam.CreateScreen(); screen1.Resolution(); screen1.ScreenMaterial(); Battery battery1 = anPhoneFactory_sam.CreateBattery(); battery1.BatteryCapacity(); battery1.StandardVoltage(); Console.Read(); } } /// <summary> /// AnPhoneFactory就是工厂的抽象角色,他并不知道产品该怎么被生产,所以只是规定了能够生产哪些产品,比如摄像头设备、屏幕设备和电池设备。 /// </summary> public abstract class AnPhoneFactory { /// <summary> /// 创建摄像头设备 /// </summary> public abstract Camera CreateCamera(); /// <summary> /// 创建屏幕设备 /// </summary> public abstract Screen CreateScreen(); /// <summary> /// 创建电池设备 /// </summary> public abstract Battery CreateBattery(); } /// <summary> /// 三个抽象设备类 有了工厂我们需要产品,毕竟工厂要负责生产产品,我们有三个产品分别是摄像头设备、屏幕设备和电池设备, /// 但是他们只是一个抽象的产品,只是定义了自己所能拥有的标准。 /// </summary> #region Herple public abstract class Camera { public abstract void Pixel(); //像素 public abstract void LensSize(); //镜头大小 } public abstract class Screen { public abstract void Resolution(); //分辨率 public abstract void ScreenMaterial(); //屏幕材质 } public abstract class Battery { public abstract void BatteryCapacity(); //电池大小 public abstract void StandardVoltage(); //标准电压 } #endregion /*产品只是定义了抽象的行为,是需要具体的产品进行完善的, *比如Sony摄像头、Sony屏幕和Sony电池以及Samsung摄像头、Samsung屏幕和Samsung电池, *从产品来说摄像头都属于抽象摄像头的具体产品,屏幕都属于抽象屏幕产品的具体产品... *所以摄像头都应该实现Camera,屏幕都应该实现Screen,电池都应该实现Battery。 */ /// <summary> /// Sony 对应An手机工厂设备返回对应需求 /// </summary> #region Sony public class SonyCamera : Camera { public override void LensSize() { Console.WriteLine(" This is Sony. camera - lens size : 1/1.67 inch."); } public override void Pixel() { Console.WriteLine(" This is Sony. camera - pixel : 2000w."); } } public class SonyScreen : Screen { public override void Resolution() { Console.WriteLine(" This is Sony. screen - resolution : 3k."); } public override void ScreenMaterial() { Console.WriteLine(" This is Sony. screen - screen material : IPS."); } } public class SonyBattery : Battery { public override void BatteryCapacity() { Console.WriteLine(" This is Sony. battery - battery capacity : 4000."); } public override void StandardVoltage() { Console.WriteLine(" This is Sony. battery - standard voltage : 3.7V."); } } #endregion /// <summary> /// Samsung 对应An手机工厂设备返回对应需求 /// </summary> #region Samsung public class SamsungCamera : Camera { public override void LensSize() { Console.WriteLine(" This is Samsung. camera - lens size : 1/1.83 inch."); } public override void Pixel() { Console.WriteLine(" This is Samsung. camera - pixel : 2300w."); } } public class SamsungScreen : Screen { public override void Resolution() { Console.WriteLine(" This is Samsung. screen - resolution : 4k."); } public override void ScreenMaterial() { Console.WriteLine(" This is Samsung. screen - screen material : Super AmoleD."); } } public class SamsungBattery : Battery { public override void BatteryCapacity() { Console.WriteLine(" This is Samsung. battery - battery capacity : 4500."); } public override void StandardVoltage() { Console.WriteLine(" This is Samsung. battery - standard voltage : 3.8~3.9V."); } } #endregion /* * 现在有了具体的产品,但是产品是需要被工厂所生产,而同一个品牌应该被同一个工厂所生产, * Sony的摄像头、屏幕和电池都应该被Sony工厂生产,而Samsung的摄像头、屏幕和电池都应该被Samsung工厂生产。 * 只是他们可能不在一个流水线,实际上在同一品牌应该都是同一个工厂。 */ #region 具体Factory /// <summary> /// Sony工厂 继承AnPhoneFactory,实现其三个设备创建方法 /// </summary> public class SonyFactory : AnPhoneFactory { public override Camera CreateCamera() { return new SonyCamera(); //返回Sony自己产生的摄像头 } public override Screen CreateScreen() { return new SonyScreen(); //返回Sony自己产生的屏幕 } public override Battery CreateBattery() { return new SonyBattery(); //返回Sony自己产生的电池 } } /// <summary> /// Samsung工厂 继承AnPhoneFactory,实现其三个设备创建方法 /// </summary> public class SamsungFactory : AnPhoneFactory { public override Camera CreateCamera() { return new SamsungCamera(); //返回Samsung自己产生的摄像头 } public override Screen CreateScreen() { return new SamsungScreen(); //返回Samsung自己产生的屏幕 } public override Battery CreateBattery() { return new SamsungBattery(); //返回Samsung自己产生的电池 } } #endregion }
- 结果
- 类图
3.扩展
产品族和产品等级
产品族:具有同一个地区、同一个厂商、同一个开发包、同一个组织模块等,但是具备不同特点或功能的产品集合,称之为是一个产品族。
产品等级:具有相同特点或功能,但是来自不同的地区、不同的厂商、不同的开发包、不同的组织模块等的产品集合,称之为是一个产品等级结构。
注意:当程序中的对象可以被划分为产品族和产品等级结构之后,那么“抽象工厂方法模式”才可以被适用。
扩展一个产品族
拓展一个产品族是非常困难的,例如产品族中新增一个CPU设备,也就是说Sony和Samsung现在可以生产CPU了,如下图所示(紫色字体为新增一个产品族需要做的事),对顶层的工厂接口类也要修改,这是非常麻烦的;
拓展一个产品等级
扩展一个产品等级,例如新增一个摄像头,也就是说新增一个品牌来生产摄像头,如下图所示(紫色字体为新增一个产品等级需要做的事),新增一个产品等级不用修改原来的代码,符合OCP原则,这是非常舒服的;
借鉴大佬文章:7.设计模式--抽象工厂模式(AbstractFactory模式)_大猫的Java笔记(公众号同号)的博客-CSDN博客_抽象工厂模式