创建型设计模式: 对类的实例化过程进行抽象,能够使软件模块做到与对象的创建和组织无关。外界对于这些对象只知道他们的公共接口,而不清楚具体的实现细节。
创建型模式重点是解决好 ( 创建什么 谁来创建 何时创建 )等问题1.Simple Factory Pattern 简单工厂模式 静态工厂模式
由一个工厂类根据传入的参量,动态决定创建出哪一类产品类的实例(参考GRASP 中的Creator Pattern:工厂类具有初始化具体产品类的数据)
特点:
(1) 被创建的对象特征: 具有共同的父类
(2) 根据不同的条件返回不同的类的实例
(3) 参与者
工厂角色:由客户调用,返回一个产品实例
抽象产品角色(共同的父类)或接口:定义 声明 产品的接口
具体产品角色:实现产品的接口
(4) 顺序图:
新建一个工厂->创建产品A->返回产品A->传递参数->创建产品B->返回产品B...
例子:
国旗生产厂
工厂角色 国旗生产厂家 类
抽象产品角色(共同的父类) 四方布
具体产品角色 中国国旗类 美国国旗类 ....
优势:
(1)外界可以从直接创建具体产品对象的尴尬局面摆脱出来
(2)明确了区分各自的职责和权力,有利于整个软件体系结构的优化
缺点:
(1)由于工厂类集中了所有实例的创建逻辑,很容易违反GRASP的高内聚的责任分配原则
(2)当具体产品类不断增多时,可能会出现要求工厂类根据不同条件使用不同工厂去创建具体实例的需求,这种对条件的判断和对具体产品类型的判断交错在一起,布利于模块功能的蔓延,对系统的扩展和维护很不利
应用:
(1)工厂类负责创建的产品类比较少
(2) "简单"模式只能用于简单的工作,呵呵~
(3) 客户只知道传入工厂类的参数,对于如何创建对象不关心
参与者:
抽象工厂 Abstract Factory :声明生成抽象产品的方法
具体工厂 Concrete Factory :执行 生成抽象产品的方法 ,生成一个 具体的产品.
抽象产品 Abstract Product :为一种产品声明接口
具体产品 Product:定义 具体工厂生成的具体产品的对象,实现产品接口
关系类:表达各产品族之间的联系类
顺序图:
client -> 创建抽象工厂a->生成产品a->生成产品b->....
client -> 创建抽象工厂b->生成产品a->生成产品b->....
实例:
扩展了的兵工厂
大陆生态系统:
//抽象大陆工厂
abstract class ContinentFactory
{
abstract public Herbivore createHerbivore();
abstract public Carnivore createCarnivore();
}
//非洲大陆,有角马 狮子
class AfricaFactory:ContinentFactory
{
override public Herbivore createHerbivore()
{
return new Wildebeest();
}
override public Carnivore createCarnivore()
{
return new Lion();
}
}
//美洲大陆,有狼/野牛
class AmericaFactory:ContinentFactory
{
override public Herbivore createHerbivore()
{
return new Bison();
}
override public Carnivore createCarnivore()
{
return new Wolf();
}
}
//食草动物
abstract class Herbivore
{
}
//食肉动物
abstract class Carnivore
{
abstract public void Eat(Herbinore h);
}
//角马/野牛 略
//狮子/狼 略
//动物世界类 (描述 在不同大陆 ,动物之间的食物链 关系责任)
class AnimalWorld
{
private Herbivore herbivore;
private Carnivore carnivore;
//创建两种动物分类
public AnimalWorld(ContinentFactory factory)
{
carnivore=factory.createCarnivore();
herbivore=factory.createHerbivore();
}
//运行食物链
public void RunFoodChain()
{
carnivore.Eat();
}
}
//测试程序
static void main()
{
//创造并运行非洲动物世界
ContinentFactory africa=new AfricaFactory();
AnimalWorld africaWorld=new AnimalWorld(africa);
africaWorld.RunFoodChain();
}
优点 :
隔离了具体类的生成,使得客户不需要知道什么被创建了.这样就使更换一个具体工厂变得相对容易.
最大好处:当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象.这对于那些需要根据当前环境来决定其行为的软件系统来说,是非常实用的一种设计模式.
缺点:
在添加新的产品对象时,难以扩展抽象工厂以便生产新种类的产品.如果要对该接口进行扩展,就需要涉及到对AbstractFactory及其所有之类的修改,显然有小小的不变,但不是很重要;
应用:
系统需要屏蔽有关对象如何创建/如何组织和如何表示
系统需要由关联的多个对象来构成
有关联的多个对象需要一起应用并且他们的约束是强迫的(不可分离)
你想提供一组对象而不显示他们的实现过程,只显示他们的接口