这次的实例讲的是在一个果园中种有3种水果,勤劳的园丁负责照看它们,当有客户需要水果的时候就给他们。
1. 工厂方法实例类图
2. Java实现代码
package
cn.edu.ynu.sei.factoryMethod;
/**
* 果园园丁接口
*
*
@author
88250
*
@version
1.0.0, 2007-8-12
* @uml.dependency supplier="cn.edu.ynu.sei.factoryMethod.Fruit"
*/
public
interface
FruitGardener
{
/**
* 工厂方法
*
*
@return
水果作物
*/
public
abstract
Fruit factory();
/**
* @uml.property name="client"
* @uml.associationEnd inverse="fruitGardener:cn.edu.ynu.sei.factoryMethod.Client"
*/
public
Client client
=
null
;
}
package
cn.edu.ynu.sei.factoryMethod;
/**
* 苹果园园丁
*
*
@author
88250
*
@version
1.0.0, 2007-8-12
*/
public
class
AppleGardener
implements
FruitGardener
{
/**
* 工厂方法,返回苹果作物的实例
*/
@Override
public
Fruit factory()
{
return
new
Apple();
}
}
package
cn.edu.ynu.sei.factoryMethod;
/**
* 草莓园园丁
*
*
@author
88250
*
@version
1.0.0, 2007-8-12
*/
public
class
StrawberryGardener
implements
FruitGardener
{
/**
* 工厂方法,返回草莓作物实例
*/
@Override
public
Fruit factory()
{
return
new
Strawberry();
}
}
package
cn.edu.ynu.sei.factoryMethod;
/**
* 葡萄园园丁
*
*
@author
88250
*
@version
1.0.0, 2007-8-12
*/
public
class
GrapeGardener
implements
FruitGardener
{
/**
* 工厂方法,返回葡萄作物对象
*/
@Override
public
Fruit factory()
{
return
new
Grape();
}
}
package
cn.edu.ynu.sei.factoryMethod;
/**
* 水果作物接口
*
@author
88250
*
@version
1.0.0, 2007-8-12
*/
public
interface
Fruit
{
/**
* 作物生长
*/
public
abstract
void
grow();
/**
* 收获作物
*/
public
abstract
void
harvest();
/**
* 种植作物
*/
public
abstract
void
plant();
}
package
cn.edu.ynu.sei.factoryMethod;
/**
* 苹果作物
*
*
@author
88250
*
@version
1.0.0, 2007-8-12
*/
public
class
Apple
implements
Fruit
{
/**
* 树龄
*/
private
int
treeAge;
/*
* (non-Javadoc)
*
* @see cn.edu.ynu.sei.factoryMethod.Fruit#grow()
*/
@Override
public
void
grow()
{
System.out.println(
"
Apple is growing....
"
);
}
/*
* (non-Javadoc)
*
* @see cn.edu.ynu.sei.factoryMethod.Fruit#harvest()
*/
@Override
public
void
harvest()
{
System.out.println(
"
Apple has been harvested.
"
);
}
/*
* (non-Javadoc)
*
* @see cn.edu.ynu.sei.factoryMethod.Fruit#plant()
*/
@Override
public
void
plant()
{
System.out.println(
"
Apple has been planted.
"
);
}
/**
* 返回树龄
*
*
@return
树龄
*/
public
int
getTreeAge()
{
return
treeAge;
}
/**
* 设置树龄
*
*
@param
treeAge
* 树龄
*/
public
void
setTreeAge(
int
treeAge)
{
this
.treeAge
=
treeAge;
}
}
package
cn.edu.ynu.sei.factoryMethod;
/**
* 草莓作物
*
*
@author
88250
*
@version
1.0.0, 2007-8-13
*/
public
class
Strawberry
implements
Fruit
{
@Override
public
void
grow()
{
System.out.println(
"
Strawberry is growing....
"
);
}
@Override
public
void
harvest()
{
System.out.println(
"
Strawberry has been harvested.
"
);
}
@Override
public
void
plant()
{
System.out.println(
"
Strawberry has been planted.
"
);
}
}
package
cn.edu.ynu.sei.factoryMethod;
/**
* 葡萄作物
*
*
@author
88250
*
@version
1.0.0, 2007-8-12
*/
public
class
Grape
implements
Fruit
{
/**
* 无籽葡萄?
*/
private
boolean
seedless;
/*
* (non-Javadoc)
*
* @see cn.edu.ynu.sei.factoryMethod.Fruit#grow()
*/
@Override
public
void
grow()
{
System.out.println(
"
Grape is growing....
"
);
}
/*
* (non-Javadoc)
*
* @see cn.edu.ynu.sei.factoryMethod.Fruit#harvest()
*/
@Override
public
void
harvest()
{
System.out.println(
"
Grape has been harvested.
"
);
}
/*
* (non-Javadoc)
*
* @see cn.edu.ynu.sei.factoryMethod.Fruit#plant()
*/
@Override
public
void
plant()
{
System.out.println(
"
Grape has been planted.
"
);
}
/**
* 是否无籽?
*
@return
*/
public
boolean
getSeedless()
{
return
seedless;
}
/**
* 设置是否无籽
*
@param
seedless
*/
public
void
setSeedless(
boolean
seedless)
{
this
.seedless
=
seedless;
}
}
package
cn.edu.ynu.sei.factoryMethod;
/**
* 果园的客户
*
*
@author
88250
*
@version
1.0.0, 2007-8-13
*/
public
class
Client
{
/**
* 主程序入口点
*
*
@param
args
* <code>null</code>
*/
public
static
void
main(String[] args)
{
Fruit apple, strawberry, grape;
fruitGardener
=
new
AppleGardener();
apple
=
fruitGardener.factory();
apple.plant();
fruitGardener
=
new
StrawberryGardener();
strawberry
=
fruitGardener.factory();
strawberry.plant();
strawberry.grow();
fruitGardener
=
new
GrapeGardener();
grape
=
fruitGardener.factory();
grape.harvest();
apple.harvest();
}
/**
* @uml.property name="fruitGardener"
* @uml.associationEnd inverse="client1:cn.edu.ynu.sei.factoryMethod.FruitGardener"
*/
private
static
FruitGardener fruitGardener;
/**
* Getter of the property <tt>fruitGardener</tt>
*
*
@return
Returns the fruitGardener.
* @uml.property name="fruitGardener"
* @uml.associationEnd inverse="client1:cn.edu.ynu.sei.factoryMethod.FruitGardener"
*/
public
FruitGardener getFruitGardener()
{
return
fruitGardener;
}
/**
* Setter of the property <tt>fruitGardener</tt>
*
*
@param
fruitGardener
* The fruitGardener to set.
* @uml.property name="fruitGardener"
* @uml.associationEnd inverse="client1:cn.edu.ynu.sei.factoryMethod.FruitGardener"
*/
public
void
setFruitGardener(FruitGardener fruitGardener)
{
Client.fruitGardener
=
fruitGardener;
}
}
3. 总结
工 厂方法模式是简单工厂模式的一个“升级”,其核心由简单工厂中的具体类变成了现在的抽象接口。这样做的好处是可以完全支持OCP,既“开-闭”原则。当系 统需要加入一个新的产品时,那么所要做的就是加入这个新产品的类以及对应的工厂类。客户端完全不用修改,也没有必要修改抽象工厂角色或者其他已有的具体工 厂角色,所以说这个模式是完全支持OCP的。
抽象工厂角色和抽象产品角色都可以选择由Java接口或者是Java抽象类来实现。如 果具体工厂角色具有共同逻辑的话,那么这些共同逻辑就可以向上移动到抽象工厂角色中,这也就意味着抽象工厂角色应该使用Java抽象类来实现,在抽象角色 里提供默认的工厂方法,相反的华就应该用Java接口实现,对抽象产品也是一样的。
这里需要注意的是任何方法都不应该复写它的基类中的已经实现的方法,否则将违反DIP
(Dependency-Inversion Principles) 依赖倒置原则,细节请参考
面向对象的设计原则摘要 。