定义:
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体类。抽象工厂模式主要解决涉及到多个产品系列的问题。
代码实例:
先回顾上一篇中工厂方法模式的例子,该示例以 BloggsCal 和 MegaCal 两种格式管理编码。如果增加更多的编码格式,这种类结构会横向增长,但如何为不同类型的 PIM 对象加入编码器,使类结构“纵向”增长呢?
这里将会用到三个相似的类层次结构,分别是预约(Appt)、待办事项(Ttd)以及联系人(Contact)。
1、创建Appt 抽象类
/**
* Appt 抽象类
* Class ApptEncoder*/
abstract classApptEncoder
{abstract public functionencode();
}
2、创建Ttd 抽象类
/**
* Ttd 抽象类
* Class TtdEncoder*/
abstract classTtdEncoder
{abstract public functionencode();
}
3、创建Contact 抽象类
/**
* Contact 抽象类
* Class ContactEncoder*/
abstract classContactEncoder
{abstract public functionencode();
}
4、创建BloggsCal Appt 格式处理类
/**
* BloggsCal Appt 格式处理类
* Class BloggsApptEncoder*/
class BloggsApptEncoder extendsApptEncoder
{public functionencode()
{//TODO: Implement encode() method.
return "Appointment data encoded in BloggsCal format\n";
}
}
5、创建BloggsCal Ttd 格式处理类
/**
* BloggsCal Ttd 格式处理类
* Class BloggsTtdEncoder*/
class BloggsTtdEncoder extendsTtdEncoder
{public functionencode()
{//TODO: Implement encode() method.
return "Ttd data encoded in BloggsCal format\n";
}
}
6、创建BloggsCal Contact 格式处理类
/**
* BloggsCal Contact 格式处理类
* Class BloggsContactEncoder*/
class BloggsContactEncoder extendsContactEncoder
{public functionencode()
{//TODO: Implement encode() method.
return "Contact data encoded in BloggsCal format\n";
}
}
7、创建MegaCal Appt 格式处理类
/**
* MegaCal Appt 格式处理类
* Class MegaApptEncoder*/
class MegaApptEncoder extendsApptEncoder
{public functionencode()
{//TODO: Implement encode() method.
return "Appointment data encoded in MegaCal format\n";
}
}
8、创建MegaCal Ttd 格式处理类
/**
* MegaCal Ttd 格式处理类
* Class MegaTtdEncoder*/
class MegaTtdEncoder extendsTtdEncoder
{public functionencode()
{//TODO: Implement encode() method.
return "Ttd data encoded in MegaCal format\n";
}
}
9、创建MegaCal Contact 格式处理类
/**
* MegaCal Contact 格式处理类
* Class MegaContactEncoder*/
class MegaContactEncoder extendsContactEncoder
{public functionencode()
{//TODO: Implement encode() method.
return "Contact data encoded in MegaCal format\n";
}
}
10、创建BloggsCal 工厂类
/**
* BloggsCal 工厂类
* Class BloggsCommsManager*/
class BloggsCommsManager extendsCommsManager
{public functiongetHeaderText()
{//TODO: Implement getHeaderText() method.
return "BloggsCal header\n";
}public functiongetApptEncoder()
{//TODO: Implement getApptEncoder() method.
return newBloggsApptEncoder();
}public functiongetTtdEncoder()
{//TODO: Implement getTtdEncoder() method.
return newBloggsTtdEncoder();
}public functiongetContractEncoder()
{//TODO: Implement getContractEncoder() method.
return newBloggsContactEncoder();
}public functiongetFooterText()
{//TODO: Implement getFooterText() method.
return "BloggsCal footer\n";
}
}
11、创建MegaCal 工厂类
/**
* MegaCal 工厂类
* Class MegaCommsManager*/
class MegaCommsManager extendsCommsManager
{public functiongetHeaderText()
{//TODO: Implement getHeaderText() method.
return "MegaCal header\n";
}public functiongetApptEncoder()
{//TODO: Implement getApptEncoder() method.
return newMegaApptEncoder();
}public functiongetTtdEncoder()
{//TODO: Implement getTtdEncoder() method.
return newMegaTtdEncoder();
}public functiongetContractEncoder()
{//TODO: Implement getContractEncoder() method.
return newMegaContactEncoder();
}public functiongetFooterText()
{//TODO: Implement getFooterText() method.
return "MegaCal footer\n";
}
}
12、调用
$mgr = newBloggsCommsManager();print $mgr->getHeaderText();print $mgr->getApptEncoder()->encode();print $mgr->getTtdEncoder()->encode();print $mgr->getContractEncoder()->encode();print $mgr->getFooterText();$mega = newMegaCommsManager();print $mega->getHeaderText();print $mega->getApptEncoder()->encode();print $mega->getTtdEncoder()->encode();print $mega->getContractEncoder()->encode();print $mega->getFooterText();
13、结果
BloggsCal headerAppointment data encoded in BloggsCal format
Ttd data encoded in BloggsCal format
Contact data encoded in BloggsCal format
BloggsCal footer
MegaCalheaderAppointment data encoded in MegaCal format
Ttd data encoded in MegaCal format
Contact data encoded in MegaCal format
MegaCal footer
总结:
1、解除了系统与实现细节间的耦合。我们可以在示例程序中添加或移除任何数量的编码类型,而不会对系统造成任何影响。
2、我们组合了系统中功能相关的元素。因此,BloggsCommsManager 可以确保只使用与 BloggsCal 格式相关的类。
3、添加新产品会非常痛苦,这是因为我们不仅需要创建新产品的实现类,还需要修改抽象创建者及其所有的实现类来支持这个新产品。