所有的创建型模式都涉及到创建对象实例的方式,因为程序不应该依赖于对象如何创建和安排,当然,使用new 是C#创建一个对象实例最简单的方法。然而,很多情况下,创建对象的本意随程序的需求不同而不同,将创建过程抽象成一个专门的“创造器”类,会使程序更灵活,更通用。
意图:
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
动机:
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?
抽象工厂模式(Abstract Factory)提供了一个创建并返回一系列相关对象的接口。
结构:
代码实现:
以红警游戏为场景(设想有两个玩家,一个是苏联一方,一个是美国一方,开始游戏后,双方开始造飞机和坦克),实现抽象工厂模式
using System; using System.Collections.Generic; using System.Text; namespace Abstract_Factory { class Program { static void Main(string[] args) { ClientManager Su = new ClientManager(new SuWeaponFactory());//苏联一方 Su.CreateWeapon(); Console.WriteLine(""); ClientManager Usa = new ClientManager(new USAWeaponFactory());//美国一方 Usa.CreateWeapon(); Console.ReadKey(); } } /// <summary> /// 制造飞机抽象类 /// </summary> public abstract class CreateFighter { public CreateFighter() { Console.Write("战斗机:"); } public abstract void createFighter(); } /// <summary> /// 制造坦克抽象类 /// </summary> public abstract class CreateTank { public CreateTank() { Console.Write("坦克:"); } public abstract void createTank(); } /// <summary> /// 兵工厂抽象类 /// </summary> public abstract class WeaponFactory { public abstract CreateFighter createFighter(); public abstract CreateTank createTank(); } /// <summary> /// 制造苏式战机类 /// </summary> public class SuCreateFighter : CreateFighter { public override void createFighter() { Console.WriteLine("Su30"); } } /// <summary> /// 制造美式战机类 /// </summary> public class USACreateFighter : CreateFighter { public override void createFighter() { Console.WriteLine("F16"); } } /// <summary> /// 制造苏式坦克类 /// </summary> public class SuCreateTank : CreateTank { public override void createTank() { Console.WriteLine("T90"); } } /// <summary> /// 制造美式坦克类 /// </summary> public class USACreateTank : CreateTank { public override void createTank() { Console.WriteLine("M1AI"); } } /// <summary> /// 苏联兵工厂类 /// </summary> public class SuWeaponFactory : WeaponFactory { public override CreateFighter createFighter() { return new SuCreateFighter(); } public override CreateTank createTank() { return new SuCreateTank(); } } /// <summary> /// 美国兵工厂类 /// </summary> public class USAWeaponFactory : WeaponFactory { public override CreateTank createTank() { return new USACreateTank(); } public override CreateFighter createFighter() { return new USACreateFighter(); } } /// <summary> /// 客户端 /// </summary> public class ClientManager { WeaponFactory weaponFactory; public ClientManager(WeaponFactory _weaponFactory) { this.weaponFactory = _weaponFactory; } /// <summary> /// 制造武器 /// </summary> public void CreateWeapon() { CreateFighter fighter = weaponFactory.createFighter(); fighter.createFighter(); CreateTank tank = weaponFactory.createTank(); tank.createTank(); } } }
Abstract Factory模式的几个要点:
1. 如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的静态工厂完全可以。
2. “系列对象”指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中的“道路”与“房屋”的依赖,“道路”与“地道”的依赖。
3. Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。
4. Abstract Factory模式经常和Factory Method模式共同组合来应对“对象创建”的需求变化。