分享
 
 
 

抽象工厂模式

王朝百科·作者佚名  2010-04-06
窄屏简体版  字體: |||超大  

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。

抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。

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

当有多个抽象产品角色时,工厂方法模式已经不能满足要求。

根据LSP原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

当每个抽象产品都有多于一个的具体子类的时候,工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产品角色都有两个具体产品。抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。

每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结果。

产品族:是指位于不同产品等级结构中,功能相关联的产品组成的家族。一般是位于不同的等级结构中的相同位置上。显然,每一个产品族中含有产品的数目,与产品等级结构的数目是相等的,形成一个二维的坐标系,水平坐标是产品等级结构,纵坐标是产品族。叫做相图。

当有多个不同的等级结构的产品时,如果使用工厂方法模式就势必要使用多个独立的工厂等级结构来对付这三个产品的等级结构。如果这些产品等级结构是平行的,会导致多个平行的工厂等级结构。

抽象工厂模式使用同一个 工厂等级结构负责三个不同产品等级结构产品对象的创建。

对于每一个产品族,都有一个具体工厂。而每一个具体工厂创建属于同一个产品族,但是分属于不同等级结构的产品。

通过引进抽象工厂模式,可以处理具有相同(或者相似)等级结构的多个产品族中的产品对象的创建问题。

由于每个具体工厂角色都需要负责两个不同等级结构的产品对象的创建,因此每个工厂角色都需要提供两个工厂方法,分别用于创建两个等级结构的产品。既然每个具体工厂角色都需要实现这两个工厂方法,所以具有一般性,不妨抽象出来,移动到抽象工厂角色中加以声明。

抽象产品角色:

public interface Creator

{

public ProductA factoryA();

public ProductB factoryB();

}

具体工厂类1:

public class ConcreteCreator1 implements Creator

{

public ProductA factoryA()

{

return new ProductA1();

}

public ProductB factoryB()

{

return new ProductB1();

}

}

具体工厂类2:

public class ConcreteCreator2 implements Creator

{

public ProductA factoryA()

{

return new ProductA1();

}

public ProductB factoryB()

{

return new ProductB1();

}

}

一般而言,有多少个产品等级结构,就会在工厂角色中发现多少个工厂方法。每一个产品等级结构中有多少个具体的产品,就有多少个产品族,也就会在工厂等级结构中发现多少个具体工厂。

抽象产品类A:

public interface ProductA

{

}

抽象产品类B:

public interface ProductB

{

}

具体产品类ProdcutA1:

public class ProductA1 implements ProductA

{

public ProductA1()

{

}

}

具体产品类ProdcutA2:

public class ProductA2 implements ProductA

{

public ProductA2()

{

}

}

具体产品类ProdcutB1:

public class ProductB1 implements ProductB

{

public ProductB1()

{

}

}

具体产品类ProdcutB2:

public class ProductB2 implements ProductB

{

public ProductB2()

{

}

}

在真实的系统中,产品等级结构的数目与每个产品等级结构中产品的数目(产品族)一般是不相等的。

抽象工厂模式的使用情况:

1.系统不依赖于产品类实例如何被创建,组合和表达的细节。

2.系统的产品有多于一个的产品族,而系统只消费其中某一族的产品(抽象工厂模式的原始用意Unix&Windows)

Button--->UnixButton/WinButton

Text----->UnixText/WinText

Unix产品族和Windows产品族,不会同时使用。

Factory--->UnixFactory/WinFactory

3.同属于同一个产品族是在一起使用的。这一约束必须在系统的设计中体现出来。

4.系统提供一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖于实现。

抽象工厂模式在农场系统的实现:

//两种抽象产品:水果、蔬菜

public interface Fruit

{

}

public interface Veggie

{

}

//四种具体产品:北方水果,热带水果,北方蔬菜,热带蔬菜

//Northern Fruit

public class NorthernFruit implements Fruit

{

private String name;

public NorthernFruit(String name)

{

}

public String getName()

{

return name;

}

public void setName(String name)

{

this.name = name;

}

}

//TropicalFruit

public class TropicalFruit implements Fruit

{

private String name;

public TropicalFruit(String name)

{

}

public String getName()

{

return name;

}

public void setName(String name)

{

this.name = name;

}

}

//NorthernVeggie

public class NorthernVeggie implements Veggie

{

private String name;

public NorthernVeggie(String name)

{

}

public String getName()

{

return name;

}

public void setName(String name)

{

this.name = name;

}

}

//TropicalVeggie

public class TropicalVeggie implements Veggie

{

private String name;

public TropicalVeggie(String name)

{

}

public String getName()

{

return name;

}

public void setName(String name)

{

this.name = name;

}

}

//抽象工厂角色

public interface Gardener

{

public Fruit createFruit(String name);

public Veggie createVeggie(String name);

}

//具体工厂角色:北方工厂,热带角色

public class NorthernGardener implements Gardener

{

public Fruit createFruit(String name)

{

return new NorthernFruit(name);

}

public Veggie createVeggie(String name)

{

return new NorthernVeggie(name);

}

}

public class TropicalGardener implements Gardener

{

public Fruit createFruit(String name)

{

return new TropicalFruit(name);

}

public Veggie createVeggie(String name)

{

return new TropicalVeggie(name);

}

}

这样客户端只需要创建具体工厂的实例,然后调用工厂对象的工厂方法就可以得到所需要的产品对象。

抽象工厂模式的另一个模式:

微型计算机配件,这个系统所需要的产品族有两个,一个系列是PC系列,另一个系列是MAC系列。

产品等级结构也有两个,一个是RAM,一个是CPU。

//两个抽象产品

public interface Cpu

{

}

public interface Ram

{

}

//四个具体产品

public class PcCpu implements Cpu

{

}

public class MacCpu implements Cpu

{

}

public class PcRam implements Ram

{

}

public class MacRam implements Ram

{

}

//抽象工厂角色

public interface ComputerProducer

{

Cpu createCpu();

Ram createRam();

}

//两个具体工厂角色

public class PcProducer implements ComputerProducer

{

public Cpu createCpu()

{

return new PcCpu();

}

public Ram createRam()

{

return new PcRam();

}

}

public class MacProducer implements ComputerProducer

{

[1]public Cpu createCpu()

{

return new MacCpu();

}

public Ram createRam()

{

return new PcRam();

}

}

一般情况下,有多少个抽象产品,就有多少个工厂方法。(比如再增加一个PC与MAC不同的其他计算机配件,例如显卡)。

OCP:

增加产品族。

增加产品等级结构。

在不改变产品等级结构的情况下,增加产品族就是意味着向每一个产品等级结构中增加一个或者多个新的具体产品角色,这时只需要向工厂等级结构中增加新的元素就可以了,具体的说,只需要增加新的具体工厂类就可以了。

在产品族数目不变的情况下,增加产品等级结构,相当于增加一个与现有产品等级结构平行的一个新的产品等级结构,这时需要向修改所有的工厂角色,增加一个新的工厂方法,这是不支持OCP的。

Producer

PcProducer MacProducer

CPU

PcCPU MacCPU

RAM

PcRAM MacCPU

在上面的结构中,增加产品族相当于增加一个新的厂商,比如Sun的CPU和RAM,这时,只需要增加一个SunProducer即可。

而增加一个新的产品等级结构相当于增加一个显卡,而显卡也有Pc和Mac之分,那么对于所有的Producer,都需要增加一个方法:createCard()

与其他设计模式的关系:

单例模式:具体工厂类可以设计成单例类,一个单例类只有一个实例,它自己向外界提供自己唯一的实例。很显然,在农场系统中,只需要NorthernGardener和TropicalGardener的一个实例就可以了。而在计算机生产的例子中,PcProducer和RamProducer也分别只需要一个实例。

工厂的工厂:工厂角色与抽象产品角色合并(简单工厂模式java.util.DateFormat),在抽象工厂模式中,抽象工厂类可以有静态方法,这个方法根据参数的值,返回对应的具体工厂类实例,但是其返回值类型是抽象工厂类型,这样可以在多态性的保证之下,允许静态工厂方法自行决定哪一个具体工厂符合要求。

//计算机生产抽象工厂角色

abstract public class ComputerProducer

{

public static ComputerProducer getProducer(String which)

{

if (which.equalsIgnoreCase("PC"))

{

return new PcProducer();

}

else if (which.equalsIgnoreCase("Mac"))

{

return new MacProducer();

}

else

{

return null;

}

}

}

工厂的工厂:工厂角色可以和具体产品角色合并(简单工厂模式),在抽象工厂模式中,每一个具体工厂类可以有一个静态方法,其返回值类型是该具体工厂类自己。

public class MacProducer extends ComputerProducer

{

private static MacProducer producer = new MacProducer();

private MacProducer() {

}

public Cpu createCpu()

{

return new MacCpu();

}

public Ram createRam()

{

return new PcRam();

}

public static MacProducer getInstance()

{

return producer;

}

}

女娲造万物的故事:

神绳(+举绳造物())

阴绳 阳绳

女人 男人

动物

雌性 雄性

在JAVA语言的AWT库中,使用了抽象工厂模式创建分水域不同操作系统的Peer构件(与本地系统相关的GUI组件)。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有