工厂模式--java

转载 2013年12月05日 22:46:11

工厂模式细分有三种,分别为:
简单工厂模式
工厂方法模式
抽象工厂模式
现单个的讲,最后再讲这三个的区别,这篇文章主要通过一个农场的实例来讲解,这也是java与模式书中的例子,
只不过我对一些部分进行了简化,一些部分进行了扩充,以帮助理解例子如下:
有一个农场公司,专门向市场销售各类水果有如下水果:
葡萄(grape)
草莓(strawberry)
苹果(apple)

简单工厂模式:

这个比较简单,写一下源代码源代码中给出了必须的注释代码比书上的要
简单一些,排版也好看一些,只是为了让新手更好的理解
Fruit.java:
public interface Fruit
{
/**
* 水果与其它植物相比有一些专门的属性,以便与农场的
* 其它植物区分开这里的水果假设它必须具备的方法:
* 生长grow()收获harvest()种植plant()
*/
void grow();
void harvest();
void plant();
}


下面是Apple类的函数Apple.java:
public class Apple implements Fruit
{
/** 
* 苹果是水果类的一种,因此它必须实现水果接口的所有方法即
* grow()harvest()plant()三个函数另外,由于苹果是多年生植物,
* 所以多出一个treeAge性质,描述苹果的树龄
*/

private int treeAge;

public void grow() { //苹果的生长函数代码 }
public void harvest() { //苹果的收获函数代码 }
public void plant() { //苹果的种植函数代码 }

public int getTreeAge() { return treeAge; }
public void setTreeAge(int treeAge) { this.treeAge = treeAge; }
}


下面是Grape类的函数Grape.java:
public class Grape implements Fruit
{
/** 
* 葡萄是水果类的一种,因此它必须实现水果接口的所有方法即
* grow()harvest()plant()三个函数另外,由于葡萄分为有籽和无籽
* 两种,因此多出一个seedless性质,描述葡萄有籽还是无籽
*/
private boolean seedless;

public void grow() { //葡萄的生长函数代码 }
public void harvest() { //葡萄的收获函数代码 }
public void plant() { //葡萄的种植函数代码 }

public boolean getSeedless() { return seedless; }
public void setSeedless(boolean seedless) { this.seedless = seedless; }

}


下面是Strawberry类的函数Strawberry.java:
public class Strawberry implements Fruit
{
/** 
* 草莓是水果类的一种,因此它必须实现水果接口的所有方法即
* grow()harvest()plant()三个函数另外,这里假设草莓分为大棚草莓和一般
* 草莓(即没有棚的草莓)因此草莓比一般水果多出一个性质coteless,描述草莓
* 是大棚草莓还是没有大棚的草莓
*/

private boolean coteless;
public void grow() { //草莓的生长函数代码 }
public void harvest() { //草莓的收获函数代码 }
public void plant() { //草莓的种植函数代码 }
public boolean getCoteless() { return coteless; }
public void setCoteless(boolean coteless) { this. coteless = coteless; }

}


农场的园丁也是系统的一部分,自然要有一个合适的类来代表,我们用FruitGardener类
来表示FruitGardener类会根据客户端的要求,创建出不同的水果对象,比如苹果(apple),
葡萄(grape)或草莓(strawberry)的实例代码如下所示:
FruitGardener.java:
public class FruitGardener
{
/**
* 通过下面的表态工厂方法,可以根据客户的需要,创建出不同的水果对象
* 如果提供的参数是apple则通过return new Apple()创建出苹果实例
* 如果是提供的参数是grape则创建葡萄实例,这正是简单工厂方法之精髓
*/
public static Fruit factory(String which) throws BadFruitException
{
if (which.equalsIgnoreCase("apple")) { return new Apple(); }
else if (which.equalsIgnoreCase("strawberry")) { return new Strawberry(); }
else if (which.equalsIgnoreCase("grape")) { return new Grape(); }
else { throw new BadFruitException("Bad fruit request"); }
}
}


简单工厂方法的优点是当在系统中引入新产品时不必修改客户端,但需要个修改工厂
类,将必要的逻辑加入到工厂类中工厂方法模式就克服了以上缺点,下面谈谈工厂方法模式

工厂方法模式:
由于水果接口以及grape类strawberry类apple类的代码都和上面的一样,所以下面相关的源码去掉了注释
Fruit.java:
public interface Fruit
{
void grow();
void harvest();
void plant();
}

Apple.java:
public class Apple implements Fruit
{
private int treeAge;
public void grow() { //苹果的生长函数代码 }
public void harvest() { //苹果的收获函数代码 }
public void plant() { //苹果的种植函数代码 }
public int getTreeAge() { return treeAge; }
public void setTreeAge(int treeAge) { this.treeAge = treeAge; }
}

Grape.java:
public class Grape implements Fruit
{
private boolean seedless;

public void grow() { //葡萄的生长函数代码 }
public void harvest() { //葡萄的收获函数代码 }
public void plant() { //葡萄的种植函数代码 }

public boolean getSeedless() { return seedless; }
public void setSeedless(boolean seedless) { this.seedless = seedless; }
}

Strawberry.java:
public class Strawberry implements Fruit
{
private boolean coteless;
public void grow() { //草莓的生长函数代码 }
public void harvest() { //草莓的收获函数代码 }
public void plant() { //草莓的种植函数代码 }
public boolean getCoteless() { return coteless; }
public void setCoteless(boolean coteless) { this. coteless = coteless; }

}



下面的源码就是工厂方法模式的重点了,在简单工厂模式中,将这里将FruitGardener定义为一个类,
即园丁要管理园里的所有水果,如果园丁哪天病了,水果都不能管理了在工厂方法模式中将FruitGardener定义为一个接口,
而将管理水果的角色划分得更细,比如有葡萄园丁草莓园丁苹果园丁等等具体角色实现FruitGardener接口的工厂方法源码如下所示:
接口FruitGardener的源码:
public interface FruitGardener
{
Fruit factory();
}



苹果园丁类AppleGardener.java的源码:
public class AppleGardener implements FruitGardener
{
public Fruit factory() { return new Apple(); }
}


葡萄园丁类GrapeGardener.java的源码:
public class GrapeGardener implements FruitGardener
{
public Fruit factory() { return new Grape(); }
}



草莓园丁类StrawberryGardener.java的源码:
public class StrawberryGardener implements FruitGardener
{
public Fruit factory() { return new Strawberry(); }
}

由以上源码可以看出,使用工厂方法模式保持了简单工厂模式的优点,克服了其缺点当在系统中引入新产品时,
既不必修改客户端,又不必修改具体工厂角色可以较好的对系统进行扩展

抽象工厂模式:
现在工厂再次大发展,要引进塑料大棚技术,在大棚里种植热带(Tropical)和亚热带的水果和蔬菜(Veggie)
其中水果分为TropicalFruit和NorthernFruit,蔬菜分为TropicalVeggie
和NorthernVeggie园丁包括TropicalGardener和NorthernGardener也就是说,
TropicalGardener专门管理TropicalFruit和TropicalGardener,NorthernGardener专门
管理NorthernFruit和NorthernVeggie抽象工厂模式在这个例子中的源码如下所示:
Fruit.java:
public interface Fruit { }

NorthernFruit.java:
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.java:
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; }
}

Veggie.java:
public interface Veggie { }

TropicalVeggie.java:
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; }
}

NorthernVeggie.java:
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; }
}

Gardener.java:
public interface Gardener
{
Fruit createFruit(String name);
Veggie createVeggie(String name);
}

TropicalGardener.java:
public class TropicalGardener implements Gardener
{
public Fruit createFruit(String name) { return new TropicalFruit(name); }
public Veggie createVeggie(String name) { return new TropicalVeggie(name); }
}

NorthernGardener.java:
public class NorthernGardener implements Gardener
{
public Fruit createFruit(String name) { return new NorthernFruit(name); }
public Veggie createVeggie(String name) { return new NorthernVeggie(name); }
}


为了简单起见,这里只讲一下增加新产品(族)时该系统如何扩展(关于产品族相关
知识,请看此书的相关章节,不过不懂产品族也没有关系,这里写得很简单,肯定能
看懂)比如现在要增加南方水果(SouthFruit)和南方蔬菜(SouthVeggie)那
么只要增加如下代码即可很容易的扩展:
SouthFruit.java:
public class SouthFruit implements Fruit
{
private String name;
public SouthFruit (String name) { }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}

SouthVeggie.java:
public class SouthVeggie implements Veggie
{
private String name;
public SouthVeggie (String name) { }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}

SouthGardener.java:
public class SouthGardener implements Gardener
{
public Fruit createFruit(String name) { return new SouthFruit(name); }
public Veggie createVeggie(String name) { return new SouthVeggie(name); }
}

五、小结

工厂方法模式仿佛已经很完美的对对象的创建进行了包装,使得客户程序中仅仅处理抽象产品角色提供的接口。那我们是否一定要在代码中遍布工厂呢?大可不必。也许在下面情况下你可以考虑使用工厂方法模式:

1)当客户程序不需要知道要使用对象的创建过程。

2)客户程序使用的对象存在变动的可能,或者根本就不知道使用哪一个具体的对象。

简单工厂模式与工厂方法模式真正的避免了代码的改动了?没有。在简单工厂模式中,新产品的加入要修改工厂角色中的判断语句;而在工厂方法模式中,要么将判断逻辑留在抽象工厂角色中,要么在客户程序中将具体工厂角色写死(就象上面的例子一样)。而且产品对象创建条件的改变必然会引起工厂角色的修改。
面对这种情况,Java的反射机制与配置文件的巧妙结合突破了限制——这在Spring中完美的体现了出来。
六、抽象工厂模式

先来认识下什么是产品族: 位于不同产品等级结构中,功能相关联的产品组成的家族。还是让我们用一个例子来形象地说明一下吧。
回到抽象工厂模式的话题上。
可以说,抽象工厂模式和工厂方法模式的区别就在于需要创建对象的复杂程度上。而且抽象工厂模式是三个里面最为抽象、最具一般性的。
抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象

而且使用抽象工厂模式还要满足一下条件:
1)系统中有多个产品族,而系统一次只可能消费其中一族产品。
2)同属于同一个产品族的产品以其使用。
来看看抽象工厂模式的各个角色(和工厂方法的如出一辙):
1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。

2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在java中它由具体的类来实现。

3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。

4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。
看过了前两个模式,对这个模式各个角色之间的协调情况应该心里有个数了,我就不举具体的例子了。只是一定要注意满足使用抽象工厂模式的条件哦。
//
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。

抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
//

相关文章推荐

c++ java 抽象工厂模式代码

  • 2016年12月31日 19:20
  • 417KB
  • 下载

简单工厂模式的C++、Java实现

  • 2017年02月04日 18:05
  • 21.84MB
  • 下载

JAVA工厂模式基本原理

引用恋枫的工厂模式基本原理一、引子        话说十年前,有一个暴发户,他家有三辆汽车——Benz奔驰、Bmw宝马、Audi奥迪,还雇了司机为他开车。不过,暴发户坐车时总是怪怪的:上Benz车后...

Java工厂模式

  • 2014年12月24日 17:49
  • 11KB
  • 下载

java工厂模式

  • 2013年05月11日 14:02
  • 12KB
  • 下载

java的工厂模式

举两个例子以快速明白Java中的简单工厂模式: 女娲抟土造人 话说:“天地开辟,未有人民,女娲抟土为人。”女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的思想里面。 女...

java-工厂模式(pdf)

  • 2008年11月03日 11:31
  • 115KB
  • 下载

java 单工厂模式

  • 2012年03月30日 08:46
  • 20KB
  • 下载

JAVA中抽象工厂模式

一、什么是抽象工厂模式 抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。 ...
  • mezheng
  • mezheng
  • 2012年07月27日 00:00
  • 996

一个简单的工厂模式(java)

  • 2016年03月23日 15:02
  • 2KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:工厂模式--java
举报原因:
原因补充:

(最多只允许输入30个字)