抽象工厂模式介绍
提供一个接口,用于创建相关或者依赖对象的家族,而不需要指定具体的实现类。
参数详解
- Participants
The classes and objects participating in this pattern are:
- AbstractFactory (ContinentFactory)
declares an interface for operations that create abstract products
- ConcreteFactory (AfricaFactory, AmericaFactory)
implements the operations to create concrete product objects
- AbstractProduct (Herbivore, Carnivore)
declares an interface for a type of product object
- Product (Wildebeest, Lion, Bison, Wolf)
defines a product object to be created by the corresponding concrete factory
implements the AbstractProduct interface
- Client (AnimalWorld)
uses interfaces declared by AbstractFactory and AbstractProduct classes
抽象工厂
//-------------------------------------------------------------------------------------
// AbstractFactoryStructrue.cs
//-------------------------------------------------------------------------------------
using UnityEngine;
using System.Collections;
public class AbstractFactoryStructrue : MonoBehaviour
{
void Start()
{
// Abstract factory #1
AbstractFactory factory1 = new ConcreteFactory1();
Client client1 = new Client(factory1);
client1.Run();
// Abstract factory #2
AbstractFactory factory2 = new ConcreteFactory2();
Client client2 = new Client(factory2);
client2.Run();
}
}
/// <summary>
/// The 'AbstractFactory' abstract class
/// </summary>
abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA();
public abstract AbstractProductB CreateProductB();
}
/// <summary>
/// The 'ConcreteFactory1' class
/// </summary>
class ConcreteFactory1 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA1();
}
public override AbstractProductB CreateProductB()
{
return new ProductB1();
}
}
/// <summary>
/// The 'ConcreteFactory2' class
/// </summary>
class ConcreteFactory2 : AbstractFactory
{
public override AbstractProductA CreateProductA()
{
return new ProductA2();
}
public override AbstractProductB CreateProductB()
{
return new ProductB2();
}
}
/// <summary>
/// The 'AbstractProductA' abstract class
/// </summary>
abstract class AbstractProductA
{
}
/// <summary>
/// The 'AbstractProductB' abstract class
/// </summary>
abstract class AbstractProductB
{
public abstract void Interact(AbstractProductA a);
}
/// <summary>
/// The 'ProductA1' class
/// </summary>
class ProductA1 : AbstractProductA
{
}
/// <summary>
/// The 'ProductB1' class
/// </summary>
class ProductB1 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Debug.Log(this.GetType().Name + " interacts with " + a.GetType().Name);
}
}
/// <summary>
/// The 'ProductA2' class
/// </summary>
class ProductA2 : AbstractProductA
{
}
/// <summary>
/// The 'ProductB2' class
/// </summary>
class ProductB2 : AbstractProductB
{
public override void Interact(AbstractProductA a)
{
Debug.Log(this.GetType().Name + " interacts with " + a.GetType().Name);
}
}
/// <summary>
/// The 'Client' class. Interaction environment for the products.
/// </summary>
class Client
{
private AbstractProductA _abstractProductA;
private AbstractProductB _abstractProductB;
// Constructor
public Client(AbstractFactory factory)
{
_abstractProductB = factory.CreateProductB();
_abstractProductA = factory.CreateProductA();
}
public void Run()
{
_abstractProductB.Interact(_abstractProductA);
}
}
抽象工厂案例1
//-------------------------------------------------------------------------------------
// AbstractFactoryPatternExample1.cs
//-------------------------------------------------------------------------------------
using UnityEngine;
using System.Collections;
//This structural code demonstrates the Abstract Factory pattern creating parallel hierarchies of objects.
//Object creation has been abstracted and there is no need for hard-coded class names in the client code.
namespace AbstractFactoryPatternExample1
{
public class AbstractFactoryPatternExample1 : MonoBehaviour
{
void Start()
{
// Create and run the African animal world
ContinentFactory africa = new AfricaFactory();
AnimalWorld world = new AnimalWorld(africa);
world.RunFoodChain();
// Create and run the American animal world
ContinentFactory america = new AmericaFactory();
world = new AnimalWorld(america);
world.RunFoodChain();
}
}
/// <summary>
/// The 'AbstractFactory' abstract class
/// </summary>
abstract class ContinentFactory
{
public abstract Herbivore CreateHerbivore();
public abstract Carnivore CreateCarnivore();
}
/// <summary>
/// The 'ConcreteFactory1' class
/// </summary>
class AfricaFactory : ContinentFactory
{
public override Herbivore CreateHerbivore()
{
return new Wildebeest();
}
public override Carnivore CreateCarnivore()
{
return new Lion();
}
}
/// <summary>
/// The 'ConcreteFactory2' class
/// </summary>
class AmericaFactory : ContinentFactory
{
public override Herbivore CreateHerbivore()
{
return new Bison();
}
public override Carnivore CreateCarnivore()
{
return new Wolf();
}
}
/// <summary>
/// The 'AbstractProductA' abstract class
/// </summary>
abstract class Herbivore
{
}
/// <summary>
/// The 'AbstractProductB' abstract class
/// </summary>
abstract class Carnivore
{
public abstract void Eat(Herbivore h);
}
/// <summary>
/// The 'ProductA1' class
/// </summary>
class Wildebeest : Herbivore
{
}
/// <summary>
/// The 'ProductB1' class
/// </summary>
class Lion : Carnivore
{
public override void Eat(Herbivore h)
{
// Eat Wildebeest
Debug.Log(this.GetType().Name +" eats " + h.GetType().Name);
}
}
/// <summary>
/// The 'ProductA2' class
/// </summary>
class Bison : Herbivore
{
}
/// <summary>
/// The 'ProductB2' class
/// </summary>
class Wolf : Carnivore
{
public override void Eat(Herbivore h)
{
// Eat Bison
Debug.Log(this.GetType().Name +" eats " + h.GetType().Name);
}
}
/// <summary>
/// The 'Client' class
/// </summary>
class AnimalWorld
{
private Herbivore _herbivore;
private Carnivore _carnivore;
// Constructor
public AnimalWorld(ContinentFactory factory)
{
_carnivore = factory.CreateCarnivore();
_herbivore = factory.CreateHerbivore();
}
public void RunFoodChain()
{
_carnivore.Eat(_herbivore);
}
}
}
抽象工厂案例2
//-------------------------------------------------------------------------------------
// AbstractFactoryPatternExample2.cs
//-------------------------------------------------------------------------------------
// allows a family of related objects without specifying the concrete class
// when there are many objects that can be added or changed dynamically
// you can model everything you can image and have those objects interact through common interfaces
// negative: can get very complicated
using UnityEngine;
using System.Collections;
namespace AbstractFactoryPatternExample2
{
public class AbstractFactoryPatternExample2 : MonoBehaviour
{
void Start ( )
{
EnemyShipBuilding ufoBuilder = new UFOEnemyShipBuilding();
ufoBuilder.orderShip(ShipType.UFO);
}
}
public enum ShipType
{
UFO
}
public abstract class EnemyShipBuilding
{
// abstract order form:
protected abstract EnemyShip MakeEnemyShip(ShipType type);
public EnemyShip orderShip(ShipType type)
{
EnemyShip ship = MakeEnemyShip(type);
ship.MakeShip();
ship.DisplayShip();
ship.FollowHeroShip();
ship.Shoot();
return ship;
}
}
public class UFOEnemyShipBuilding : EnemyShipBuilding
{
// Make Ship varies per ship type...
protected override EnemyShip MakeEnemyShip(ShipType type)
{
EnemyShip ship = null;
if (type == ShipType.UFO)
{
IEnemyShipFactory factory = new UFOEnemyShipFactory();
ship = new UFOEnemyShip(factory);
ship.name = "UFO";
}
return ship;
}
}
public interface IEnemyShipFactory
{
IESWeapon AddESGun();
IESEngine AddESEngine();
}
public class UFOEnemyShipFactory : IEnemyShipFactory
{
// each factory can add different weapons and stuff
public IESWeapon AddESGun()
{
return new ESUFOGun();
}
public IESEngine AddESEngine()
{
return new ESUFOEngine();
}
}
public abstract class EnemyShip
{
public string name;
protected IESEngine engine;
protected IESWeapon weapon;
public abstract void MakeShip();
public void DisplayShip()
{
Debug.Log(name + " is on the screen.");
}
public void FollowHeroShip()
{
Debug.Log(name + " follows hero ship with " + engine.ToStringEX());
}
public void Shoot()
{
Debug.Log(name + " shoots and does " + weapon.ToStringEX());
}
public string ToStringEX()
{
return "The " + name + " has a speed of " + engine.ToStringEX() + " a firepower of " + weapon.ToStringEX();
}
}
public class UFOEnemyShip : EnemyShip
{
IEnemyShipFactory factory;
public UFOEnemyShip(IEnemyShipFactory factory)
{
this.factory = factory;
}
public override void MakeShip()
{
Debug.Log("Making enemy ship " + name);
weapon = factory.AddESGun();
engine = factory.AddESEngine();
}
}
// possible Weapons to swap in and out
public interface IESWeapon
{
string ToStringEX();
}
public interface IESEngine
{
string ToStringEX();
}
public class ESUFOGun : IESWeapon
{
public string ToStringEX()
{
return "20 damage";
}
}
public class ESUFOEngine : IESEngine
{
public string ToStringEX()
{
return "1000 mph";
}
}
}