今天我们来看一下另一个使用频率非常高的抽象工厂模式,看完原理分别给出.NET和JAVA两种语言的实现源码。
定义:
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
Abstract Factory Pattern: Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
又称为工具(Kit)模式
抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品
当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率
分析:
每个具体工厂只有一个或者一组重载的工厂方法,只能生产一种产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销
一个工厂可以生产一系列产品(一族产品),极大减少了工厂类的数量
产品等级结构:产品等级结构即产品的继承结构
产品族:产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品
类图:
抽象工厂模式包含以下4个角色:
AbstractFactory(抽象工厂)
ConcreteFactory(具体工厂)
AbstractProduct(抽象产品)
ConcreteProduct(具体产品)
适用性:
一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节
系统中有多于一个的产品族,但每次只使用其中某一产品族
属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来
产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的产品等级结构
优点:
隔离了具体类的生成,使得客户端并不需要知道什么被创建
当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象
增加新的产品族很方便,无须修改已有系统,符合开闭原则
缺点:
增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了开闭原则
@增加产品族
对于增加新的产品族,抽象工厂模式很好地支持了开闭原则,只需要增加具体产品并对应增加一个新的具体工厂,对已有代码无须做任何修改
@增加新的产品等级结构
对于增加新的产品等级结构,需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加生产新产品的方法,违背了开闭原则
案例1:(.NET代码)
代码清单包括:
Program.cs
using System;
using System.Configuration;
using System.Reflection;
namespace AbstractFactorySample
{
class Program
{
static void Main(string[] args)
{
//使用抽象层定义
SkinFactory factory;
Button bt;
TextField tf;
ComboBox cb;
//读取配置文件
string factoryType = ConfigurationManager.AppSettings["factory"];
//反射生成对象
factory = (SkinFactory)Assembly.Load("AbstractFactorySample").CreateInstance(factoryType);
bt = factory.CreateButton();
tf = factory.CreateTextField();
cb = factory.CreateComboBox();
bt.Display();
tf.Display();
cb.Display();
Console.Read();
}
}
}
Button.cs
namespace AbstractFactorySample
{
interface Button
{
void Display();
}
}
SpringButton.cs
using System;
namespace AbstractFactorySample
{
class SpringButton : Button
{
public void Display()
{
Console.WriteLine("显示浅绿色按钮。");
}
}
}
SummerButton.cs
using System;
namespace AbstractFactorySample
{
class SummerButton : Button
{
public void Display()
{
Console.WriteLine("显示浅蓝色按钮。");
}
}
}
TextField.cs
namespace AbstractFactorySample
{
interface TextField
{
void Display();
}
}
SpringTextField.cs
using System;
namespace AbstractFactorySample
{
class SpringTextField : TextField
{
public void Display()
{
Console.WriteLine("显示绿色边框文本框。");
}
}
}
SummerTextField.cs
using System;
namespace AbstractFactorySample
{
class SummerTextField : TextField
{
public void Display()
{
Console.WriteLine("显示蓝色边框文本框。");
}
}
}
ComboBox.cs
namespace AbstractFactorySample
{
interface ComboBox
{
void Display();
}
}
SpringComboBox.cs
using System;
namespace AbstractFactorySample
{
class SpringComboBox : ComboBox
{
public void Display()
{
Console.WriteLine("显示绿色边框组合框。");
}
}
}
SummerComboBox.cs
using System;
namespace AbstractFactorySample
{
class SummerComboBox : ComboBox
{
public void Display()
{
Console.WriteLine("显示蓝色边框组合框。");
}
}
}
SkinFactory.cs
namespace AbstractFactorySample
{
interface SkinFactory
{
Button CreateButton();
TextField CreateTextField();
ComboBox CreateComboBox();
}
}
SpringSkinFactory.cs
namespace AbstractFactorySample
{
class SpringSkinFactory : SkinFactory
{
public Button CreateButton()
{
return new SpringButton();
}
public TextField CreateTextField()
{
return new SpringTextField();
}
public ComboBox CreateComboBox()
{
return new SpringComboBox();
}
}
}
SummerSkinFactory.cs
namespace AbstractFactorySample
{
class SummerSkinFactory : SkinFactory
{
public Button CreateButton()
{
return new SummerButton();
}
public TextField CreateTextField()
{
return new SummerTextField();
}
public ComboBox CreateComboBox()
{
return new SummerComboBox();
}
}
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="factory" value="AbstractFactorySample.SpringSkinFactory"/>
</appSettings>
</configuration>
案例2:(JAVA代码)
AbstractFactory
public interface IAnimalFactory {
ICat createCat();
IDog createDog();
}
ConcreteFactory
public class BlackAnimalFactory implements IAnimalFactory {
public ICat createCat() {
return new BlackCat();
}
public IDog createDog() {
return new BlackDog();
}
}
public class WhiteAnimalFactory implements IAnimalFactory {
public ICat createCat() {
return new WhiteCat();
}
public IDog createDog() {
return new WhiteDog();
}
}
AbstractProduct
public interface ICat {
void eat();
}
public interface IDog {
void eat();
}
ConcreteProduct
public class BlackCat implements ICat {
public void eat() {
System.out.println("The black cat is eating!");
}
}
public class WhiteCat implements ICat {
public void eat() {
System.out.println("The white cat is eating!");
}
}
public class BlackDog implements IDog {
public void eat() {
System.out.println("The black dog is eating");
}
}
public class WhiteDog implements IDog {
public void eat() {
System.out.println("The white dog is eating!");
}
}
Test
public static void main(String[] args) {
IAnimalFactory blackAnimalFactory = new BlackAnimalFactory();
ICat blackCat = blackAnimalFactory.createCat();
blackCat.eat();
IDog blackDog = blackAnimalFactory.createDog();
blackDog.eat();
IAnimalFactory whiteAnimalF*ctory = new WhiteAnimalFactory();
ICat whiteCat = whiteAnimalFactory.createCat();
whiteCat.eat();
IDog whiteDog = whiteAnimalFactory.createDog();
whiteDog.eat();
}
程序运行返回结果:
The black cat is eating! The black dog is eating! The white cat is eating! The white dog is eating!