《java与模式》笔记(十) 抽象工厂模式

ξ 14.1 引言

☆ 抽象工厂模式的用意:抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象。

☆ 对抽象工厂模式理解的三个步骤:
① 当系统中有多个抽象产品角色的时候,假设产生抽象产品角色的是实现了抽象工厂角色的具体工厂角色。

② 阶段一的假设无法成立,因为抽象产品角色无法被实例化。根据里氏替代原则,可以让具体工厂角色产生抽象产品角色的实现类,即具体产品角色。

③ 如果抽象产品角色有多个具体实例即具体产品角色,那么工厂(具体和抽象)角色应该提供不同的方法产生不同的具体产品角色。


ξ 14.2 问题
☆ 产品族:是指位于不同产品等级结构中,功能相关联的产品组成的家族。下图详细说明产品等级结构和产品族的关系:

从上图可以看出,对应的每一个产品族,都由一个具体工厂负责创建,在同一产品族中不同等级结构上的具体产品,由具体工厂的每个方法创建。

ξ 14.3 抽象工厂模式的结构
☆ 假设一个子系统需要一些产品对象,而这些产品又属于一个以上的产品等级结构。那么为了将消费这些产品对象的责任和创建这些产品对象的责任分割开,可以引入抽象工厂模式。这样的话,消费产品的一方不需要直接参与产品的创建工作,而只需要向一个公共的工厂接口请求所需要的产品。下面举例说明这种结构:

图中有两个等级结构,A和B。两个产品族1和2。可以看到,对于一个产品族有一个实现了抽象工厂角色的具体工厂角色(ProductA1和ProductA2对应ConcreteCreator1,ProductA2和ProductB2对应ConcreteCreator2),而同一个产品族内不同的等级结构,对应具体工厂角色里面的不同方法(ProductA1和ProductA2对应factoryA方法,ProductB1和ProductB2对应factoryB方法)。下面是源代码:

public   interface  Creator
{
    ProductA factoryA();
    ProductB factoryB();
}


public   class  ConcreteCreator1  implements  Creator
{
    
public ProductA factoryA()
    
{
        
return new ProductA1() ;
    }

    
    
public ProductB factoryB()
    
{
        
return new ProductB1() ;
    }

}


public   class  ConcreteCreator2  implements  Creator
{
    
public ProductA factoryA()
    
{
        
return new ProductA2() ;
    }

    
    
public ProductB factoryB()
    
{
        
return new ProductB2() ;
    }

}


public   interface  ProductA
{
}


public   class  ProductA1  implements  ProductA
{
    
public ProductA1() {}
}


public   class  ProductA2  implements  ProductA
{
    
public ProductA2() {}
}


public   interface  ProductB
{
}


public   class  ProductB1  implements  ProductB
{
    
public ProductB1() {}
}


public   class  ProductB2  implements  ProductB
{
    
public ProductB2() {}
}

ξ 14.4 在什么情况下应该使用抽象工厂模式
① 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是很重要的;
② 这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品;
③ 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。
④ 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

ξ 14.7 “开-闭”原则
当抽象工厂模式中新加产品族的时候,只需要添加抽象工厂角色和抽象产品角色的具体角色并建立起相应的关系就可以,这个时候抽象工厂模式是支持“开-闭”原则的;
当增加产品等级结构时,需要改动抽象工厂角色和修改每个具体工厂角色,这个时候,抽象工厂模式是不满足“开-闭”原则的。
综合来看,抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品族的增加提供方便,而不能为新的产品等级结构的增加提供这样的方便。
 
=============================
最后总结一下:
☆ 首先举一个比较具体的例子。在UI设计中,一般会有许多控件,比如按钮(Button)和文本框(Text),这里Button和Text就是两个等级结构的产品。而为了在Windows和Macintosh系统中提供不同的效果,需要有Windows Button、Windows Text,同理会有Macintosh Button和Macintosh Text,这里Windows和Macintosh就是两个产品族,下图说明了它们之间的关系:

下面是源代码:

//  首先是Factory接口,它是抽象工厂角色
public   interface  Factory
{
    
// 创建按钮
    Button createButton();

    
// 创建文本框
    Text createText();
}


//  下面是Factory接口的默认实现,这里使用了默认适配模式
public   abstract   class  AbstractFactory  implements  Factory
{
    
// 抽象方法,派生类实现
    public abstract Button createButton();
    
    
// 抽象方法,派生类实现
    public abstract Text createText();
    
    
// 根据标识选择创建何种具体工厂角色(选择产品族)
    public static Factory getFactory(String flag)
    
{
        Factory result 
= null ;

        
if( flag.equalsIgnoreCase("macintosh") )
        
{
            result 
= MacFactory.getInstance() ;
        }

        
else if( flag.equalsIgnoreCase("windows") )
        
{
            result 
= WinFactory.getInstance() ;
        }

        
        
return result ;
    }

}


//  下面是Macintosh产品族的具体工厂角色
public   class  MacFactory  extends  AbstractFactory
{
    
// 单例模式,私有构造函数
    private MacFactory() {}

    
// 创建Macintosh产品族按钮
    public Button createButton()
    
{
        
return new MacButton() ;
    }

    
    
// 创建Macintosh产品族文本框
    public Text createText()
    
{
        
return new MacText() ;
    }

    
    
// 提供单例的方法
    synchronized public static Factory getInstance()
    
{
        
ifnull == _instance )
            _instance 
= new MacFactory() ;
        
        
return _instance ;
    }

    
    
private static MacFactory _instance = null ;
}


//  下面是Widnows产品族的具体工厂角色
public   class  WinFactory  extends  AbstractFactory
{
    
// 单例模式,私有构造函数
    private WinFactory() {}

    
// 创建Widnows产品族按钮
    public Button createButton()
    
{
        
return new WinButton() ;
    }

    
    
// 创建Widnows产品族文本框
    public Text createText()
    
{
        
return new WinText() ;
    }

    
    
// 提供单例的方法
    synchronized public static Factory getInstance()
    
{
        
ifnull == _instance )
            _instance 
= new WinFactory() ;
        
        
return _instance ;
    }


    
private static WinFactory _instance = null ;
}


//  下面是等级结构中Button的抽象产品角色
public   interface  Button
{
}


//  下面是Button的Macintosh产品族具体产品角色
public   class  MacButton  implements  Button
{
    
public MacButton() {}
}


//  Button的Windows产品族具体产品角色
public   class  WinButton  implements  Button
{
    
public WinButton() {}
}


//  等级结构中Text的抽象产品角色
public   interface  Text
{
}


//  Text的Macintosh产品族具体产品角色
public   class  MacText  implements  Text
{
    
public MacText() {}
}


//  Text的Windows产品族具体产品角色
public   class  WinText  implements  Text
{
    
public WinText() {}
}


☆ 下面给出三种常见形态的工厂模式的相图,依次是抽象工厂模式、工厂方法模式和简单工厂模式:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值