转自http://blog.csdn.net/DL88250/archive/2007/08/13/1741590.aspx
本次实例继续上次 工厂方法 中的果园农场。这次,该农场公司引进塑料大棚技术,在大棚里种植热带(Tropical)水果和蔬菜。
1. 抽象工厂实例类图
2. Java实现代码
package
cn.edu.ynu.sei.abstractFactory;
/**
* 水果接口
*
@author
88250
*
@version
1.0.0, 2007-8-13
*
@see
cn.edu.ynu.sei.factoryMethod.Fruit
*/
public
interface
Fruit
{
}
package
cn.edu.ynu.sei.abstractFactory;
/**
* 热带水果
*
*
@author
88250
*
@version
1.0.0, 2007-8-13
*/
public
class
TropicalFruit
implements
Fruit
{
/**
* 水果名
*/
private
String name;
/**
* 构造器
*
@param
name 果名
*/
public
TropicalFruit(String name)
{
this
.name
=
name;
}
/**
*
@return
the name
*/
public
String getName()
{
return
name;
}
/**
*
@param
name the name to set
*/
public
void
setName(String name)
{
this
.name
=
name;
}
}
package
cn.edu.ynu.sei.abstractFactory;
/**
* 北方水果接口
*
*
@author
88250
*
@version
1.0.0, 2007-8-13
*/
public
class
NorthernFruit
implements
Fruit
{
/**
* 水果名
*/
private
String name;
/**
* 构造器
*
@param
name 果名
*/
public
NorthernFruit(String name)
{
this
.name
=
name;
}
/**
*
@return
the name
*/
public
String getName()
{
return
name;
}
/**
*
@param
name the name to set
*/
public
void
setName(String name)
{
this
.name
=
name;
}
}
package
cn.edu.ynu.sei.abstractFactory;
/**
* 蔬菜接口
*
*
@author
88250
*
@version
1.0.0, 2007-8-13
*
@see
cn.edu.ynu.sei.factoryMethod.Fruit
*/
public
interface
Veggie
{
}
package
cn.edu.ynu.sei.abstractFactory;
/**
* 北方蔬菜
*
*
@author
88250
*
@version
1.0.0, 2007-8-13
*/
public
class
NorthernVeggie
implements
Veggie
{
/**
* 蔬菜名
*/
private
String name;
/**
* 构造器
*
@param
name 蔬菜名
*/
public
NorthernVeggie(String name)
{
this
.name
=
name;
}
/**
*
@return
the name
*/
public
String getName()
{
return
name;
}
/**
*
@param
name the name to set
*/
public
void
setName(String name)
{
this
.name
=
name;
}
}
package
cn.edu.ynu.sei.abstractFactory;
/**
* 热带蔬菜
*
*
@author
88250
*
@version
1.0.0, 2007-8-13
*/
public
class
TropicalVeggie
implements
Veggie
{
/**
* 蔬菜名
*/
private
String name;
/**
* 构造器
*
@param
name 蔬菜名
*/
public
TropicalVeggie(String name)
{
this
.name
=
name;
}
/**
*
@return
the name
*/
public
String getName()
{
return
name;
}
/**
*
@param
name the name to set
*/
public
void
setName(String name)
{
this
.name
=
name;
}
}
package
cn.edu.ynu.sei.abstractFactory;
/**
* 园丁接口
*
*
@author
88250
*
@version
1.0.0, 2007-8-13
*/
public
interface
Gardener
{
/**
* 水果工厂方法,产出一种水果
*
@param
name 水果名
*
@return
水果
*/
public
abstract
Fruit createdFruit(String name);
/**
* 蔬菜的工厂方法产出一种蔬菜
*
@param
name 蔬菜名
*
@return
蔬菜
*/
public
abstract
Veggie createVeggie(String name);
}
package
cn.edu.ynu.sei.abstractFactory;
/**
* 北方园园丁
*
*
@author
88250
*
@version
1.0.0, 2007-8-13
*/
public
class
NorthenGardener
implements
Gardener
{
@Override
public
Fruit createdFruit(String name)
{
return
new
NorthernFruit(name);
}
@Override
public
Veggie createVeggie(String name)
{
return
new
NorthernVeggie(name);
}
}
package
cn.edu.ynu.sei.abstractFactory;
/**
* 热带园园丁
*
*
@author
88250
*
@version
1.0.0, 2007-8-13
*/
public
class
TropicalGardener
implements
Gardener
{
@Override
public
Fruit createdFruit(String name)
{
return
new
TropicalFruit(name);
}
@Override
public
Veggie createVeggie(String name)
{
return
new
TropicalVeggie(name);
}
}
3. 总结
这里我们还是讨论一下抽象工厂模式对面向对象原则中最基本的OCP原则的支持。
当增加一个新的产品族的时候我们只需要向系统中加入新的具体工厂角色和对应的具体产品角色,不需要修改原有的工厂或产品角色的代码,所以此时抽象模式是完全支持OCP的。
当增加新的产品等级结构时就需要修改相关的具体工厂代码。例如在农场公司系统中有一种热带水果类别继承于现用热带水果类别,这时我们不得不修改热带水果具体工厂的代码,新增加一个工厂方法给它。这样是不符合OCP的。
所以抽象工厂只是在一定程度上支持OCP的,在设计的时候这点很值得我们注意。