目录
1.基础
抽象工厂结构图
抽象类和接口
2.实现
3.扩展
产品族和产品等级
扩展一个产品族
编辑拓展一个产品等级
抽象工厂模式->创建型设计模式
定义:提供一个接口,可以创建一系列相关或相互依赖的对象,而无需指定它们具体的类。(理解:利用抽象工厂模式,产生一个类似模板的抽象类,例如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.一个类一次可以实现若干个接口,但是只能扩展一个父类;
...
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();
}
}
///
/// AnPhoneFactory就是工厂的抽象角色,他并不知道产品该怎么被生产,所以只是规定了能够生产哪些产品,比如摄像头设备、屏幕设备和电池设备。
///
public abstract class AnPhoneFactory
{
///
/// 创建摄像头设备
///
public abstract Camera CreateCamera();
///
/// 创建屏幕设备
///
public abstract Screen CreateScreen();
///
/// 创建电池设备
///
public abstract Battery CreateBattery();
}
///
/// 三个抽象设备类 有了工厂我们需要产品,毕竟工厂要负责生产产品,我们有三个产品分别是摄像头设备、屏幕设备和电池设备,
/// 但是他们只是一个抽象的产品,只是定义了自己所能拥有的标准。
///
#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。
*/
///
/// Sony 对应An手机工厂设备返回对应需求
///
#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
///
/// Samsung 对应An手机工厂设备返回对应需求
///
#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
///
/// Sony工厂 继承AnPhoneFactory,实现其三个设备创建方法
///
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自己产生的电池
}
}
///
/// Samsung工厂 继承AnPhoneFactory,实现其三个设备创建方法
///
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
}
产品族:具有同一个地区、同一个厂商、同一个开发包、同一个组织模块等,但是具备不同特点或功能的产品集合,称之为是一个产品族。
产品等级:具有相同特点或功能,但是来自不同的地区、不同的厂商、不同的开发包、不同的组织模块等的产品集合,称之为是一个产品等级结构。
注意:当程序中的对象可以被划分为产品族和产品等级结构之后,那么“抽象工厂方法模式”才可以被适用。
拓展一个产品族是非常困难的,例如产品族中新增一个CPU设备,也就是说Sony和Samsung现在可以生产CPU了,如下图所示(紫色字体为新增一个产品族需要做的事),对顶层的工厂接口类也要修改,这是非常麻烦的;
扩展一个产品等级,例如新增一个摄像头,也就是说新增一个品牌来生产摄像头,如下图所示(紫色字体为新增一个产品等级需要做的事),新增一个产品等级不用修改原来的代码,符合OCP原则,这是非常舒服的;
借鉴大佬文章:7.设计模式--抽象工厂模式(AbstractFactory模式)_大猫的Java笔记(公众号同号)的博客-CSDN博客_抽象工厂模式