设计模式详解:抽象工厂模式

今天我们来看一下另一个使用频率非常高的抽象工厂模式,看完原理分别给出.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代码)

 代码清单包括:

ü (1) Button :按钮接口,充当抽象产品
ü (2) SpringButton Spring 按钮类,充当具体产品
ü (3) SummerButton Summer 按钮类,充当具体产品
ü (4) TextField :文本框接口,充当抽象产品
ü (5) SpringTextField Spring 文本框类,充当具体产品
ü (6) SummerTextField Summer 文本框类,充当具体产品
ü (7) ComboBox :组合框接口,充当抽象产品
ü (8) SpringComboBox Spring 组合框类,充当具体产品
ü (9) SummerComboBox Summer 组合框类,充当具体产品
ü (10) SkinFactory :界面皮肤工厂接口,充当抽象工厂
ü (11) SpringSkinFactory Spring 皮肤工厂,充当具体工厂
ü (12) SummerSkinFactory Summer 皮肤工厂,充当具体工厂
ü (13) 配置文件 App.config
ü (14) Program :客户端测试类

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!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乱世刀疤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值