// TODO 自动生成的方法存根
System.out.println("香蕉口味的冰淇淋");
}
}
4、草莓口味的冰淇淋? StrawberryIceCream.java
[java] view plain copy
print ?
-
package?com.simplefactory.test;??
-
/**?
-
?*?草莓口味的冰淇淋?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?StrawberryIceCream?implements?IceCream?{??
-
????@Override??
-
????public?void?taste()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????System.out.println(”草莓口味的冰淇淋”);??
-
????}??
- }??
package com.simplefactory.test;
/**
-
草莓口味的冰淇淋
-
@author ThinkPad
*/
public class StrawberryIceCream implements IceCream {
@Override
public void taste() {
// TODO 自动生成的方法存根
System.out.println("草莓口味的冰淇淋");
}
}
**
5、生产冰淇淋的机器(简单工厂) IceCreamFactory.java**
[java] view plain copy
print ?
-
package?com.simplefactory.test;??
-
/**?
-
?*?简单冰淇淋工厂类?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?IceCreamFactory?{??
-
????/**?
-
?????*?生产冰淇淋的方法?
-
?????*?@param?flavour??哪种口味?
-
?????*?@return?
-
?????*/??
-
????public?static?IceCream?produceIceCream(String??flavour){??
-
????????IceCream?iceCream?=?null;??
-
????????if(flavour.equals(“banana”)){??
-
????????????iceCream?=?new?BananaIceCream();??
-
????????}else?if(flavour.equals(“apple”)){??
-
????????????iceCream?=?new?AppleIceCream();??
-
????????}else?if(flavour.equals(“strawberry”)){??
-
????????????iceCream?=?new?StrawberryIceCream();??
-
????????}else?{??
-
????????????throw?new?IllegalArgumentException(“没有该口味”);??
-
????????}??
-
????????return?iceCream;??
-
????}??
- }??
package com.simplefactory.test;
/**
-
简单冰淇淋工厂类
-
@author ThinkPad
*/
public class IceCreamFactory {
/**
-
生产冰淇淋的方法
-
@param flavour 哪种口味
- @return
*/
public static IceCream produceIceCream(String flavour){
IceCream iceCream = null;
if(flavour.equals("banana")){
iceCream = new BananaIceCream();
}else if(flavour.equals("apple")){
iceCream = new AppleIceCream();
}else if(flavour.equals("strawberry")){
iceCream = new StrawberryIceCream();
}else {
throw new IllegalArgumentException("没有该口味");
}
return iceCream;
}
}
6、客户端调用
[java] view plain copy
print ?
-
package?com.simplefactory.test;??
-
/**?
-
?*?客户端示例?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?Console?{??
-
????public?static?void?main(String[]?args)?{??
-
????????//?TODO?自动生成的方法存根??
-
????????IceCream cream1 = IceCreamFactory.produceIceCream( ”apple” );??
-
????????cream1.taste();??
-
????????IceCream cream2 = IceCreamFactory.produceIceCream( ”strawberry” );??
-
????????cream2.taste();??
-
????????IceCream cream3 = IceCreamFactory.produceIceCream( ”unkown” );??
-
????????cream3.taste();??
-
????}??
- }??
package com.simplefactory.test;
/**
-
客户端示例
-
@author ThinkPad
*/
public class Console {
public static void main(String[] args) {
// TODO 自动生成的方法存根
IceCream cream1 = IceCreamFactory.produceIceCream("apple");
cream1.taste();
IceCream cream2 = IceCreamFactory.produceIceCream("strawberry");
cream2.taste();
IceCream cream3 = IceCreamFactory.produceIceCream("unkown");
cream3.taste();
}
}
事实上,这就是个简单工厂模式的样例了!上例的UML类图如下:
[](()三、想吃哪种口味的冰淇淋就去找哪种机器吧
=========================================================================================
可以看到,冰淇淋的制作工作交给了那台机器—— IceCreamFactory 来负责了。不过,这台机器负责制作所有口味的冰淇淋,用户要“告诉”它自己需要的口味。这样也是有缺点的,当有一天又增加了新的口味的冰淇淋时,那么商城不得不对这台机器进行改造,拆开它,改造它的内部调用机制,增加新的口味的制作逻辑,它提供给用户的输入按钮也要增加一个选择。总之这违背了“开闭”原则,商城不得不去改造这台机器。
终于,商城意识到了这一点。于是,它想出了更好的方法。
商城针对不同口味的冰淇淋设计了不同的机器(也许它们之间的差异很小),它们各自只制作自己口味的冰淇淋,它们的个头比原先的那个负责制作所有口味的冰淇淋的机器要小得多。商城把它们并排放在一起,在上面贴好标签,“苹果味”、“香蕉味”、“草莓味”等等。这样,客户只需要到自己想要的口味的机器下去拿就行了。那么以后,如果要出某种新的口味,商城只需要再造个相应的机器放在旁边就行了,不需要去改造什么了。我们用代码实现下:
1、IceCream.java、AppleIceCream.java、BananaIceCream.java、StrawberryIceCream.java同以上简单工厂方法示例。
2、抽象冰淇淋工厂类 IceCreamFactory.java
[java] view plain copy
print ?
-
package ?com.factorymethod.test;??
-
/**?
-
?* 抽象冰淇淋工厂类?
-
?* @author ThinkPad?
-
?*?
-
?*/??
-
public abstract class ?IceCreamFactory {????
-
????/**?
-
?????* 抽象的生产冰淇淋方法?
-
?????* @return?
-
?????*/??
-
????protected abstract ?IceCream produceIceCream();???
- }??
package com.factorymethod.test;
/**
-
抽象冰淇淋工厂类
-
@author ThinkPad
*/
public abstract class IceCreamFactory {
/**
-
抽象的生产冰淇淋方法
- @return
*/
protected abstract IceCream produceIceCream();
}
3、苹果口味的冰淇淋工厂 AppleIceCreamFactory.java
[java] view plain copy
print ?
-
package ?com.factorymethod.test;??
-
/**?
-
?* 苹果口味的冰淇淋工厂?
-
?* @author ThinkPad?
-
?*?
-
?*/??
-
public?class?AppleIceCreamFactory?extends?IceCreamFactory?{??
-
????@Override??
-
????protected?IceCream?produceIceCream()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????return?new?AppleIceCream();??
-
????}??
- }??
package com.factorymethod.test;
/**
-
苹果口味的冰淇淋工厂
-
@author ThinkPad
*/
public class AppleIceCreamFactory extends IceCreamFactory {
@Override
protected IceCream produceIceCream() {
// TODO 自动生成的方法存根
return new AppleIceCream();
}
}
**
4、香蕉口味的冰淇淋工厂? BananaIceCreamFactory.java**
[java] view plain copy
print ?
-
package?com.factorymethod.test;??
-
/**?
-
?*?香蕉口味的冰淇淋工厂?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?BananaIceCreamFactory?extends?IceCreamFactory?{??
-
????@Override??
-
????protected?IceCream?produceIceCream()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????return?new?BananaIceCream();??
-
????}??
- }??
package com.factorymethod.test;
/**
-
香蕉口味的冰淇淋工厂
-
@author ThinkPad
*/
public class BananaIceCreamFactory extends IceCreamFactory {
@Override
protected IceCream produceIceCream() {
// TODO 自动生成的方法存根
return new BananaIceCream();
}
}
5、草莓口味的冰淇淋工厂 StrawberryIceCreamFactory.java
[java] view plain copy
print ?
-
package?com.factorymethod.test;??
-
/**?
-
?*?草莓口味的冰淇淋工厂?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?StrawberryIceCreamFactory?extends?IceCreamFactory?{??
-
????@Override??
-
????protected?IceCream?produceIceCream()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????return new ?StrawberryIceCream();???
-
????}??
- }??
package com.factorymethod.test;
/**
-
草莓口味的冰淇淋工厂
-
@author ThinkPad
*/
public class StrawberryIceCreamFactory extends IceCreamFactory {
@Override
protected IceCream produceIceCream() {
// TODO 自动生成的方法存根
return new StrawberryIceCream();
}
}
6、客户端示例
[java] view plain copy
print ?
-
package ?com.factorymethod.test;??
-
/**?
-
?* 客户端示例?
-
?* @author ThinkPad?
-
?*?
-
?*/??
-
public class ?Console {???
-
????public static void ?main(String[] args) {????
-
????????// TODO 自动生成的方法存根??
-
????????// 要草莓味的冰淇淋??
-
????????IceCream c1 =? new ?StrawberryIceCreamFactory().produceIceCream();??
-
????????c1.taste();??
-
????????// 要香蕉味的冰淇淋??
-
????????IceCream c2 =? new ?BananaIceCreamFactory().produceIceCream();??
-
????????c2.taste();??
-
????}??
- }??
package com.factorymethod.test;
/**
-
客户端示例
-
@author ThinkPad
*/
public class Console {
public static void main(String[] args) {
// TODO 自动生成的方法存根
// 要草莓味的冰淇淋
IceCream c1 = new StrawberryIceCreamFactory().produceIceCream();
c1.taste();
// 要香蕉味的冰淇淋
IceCream c2 = new BananaIceCreamFactory().produceIceCream();
c2.taste();
}
}
那么,你应该猜到了,这就是个工厂方法模式的实例喽!该例的UML图如下:
[](()四、冰淇淋升级了:国产奶油和进口奶油
=======================================================================================
冰淇淋的生意越来越好了,商城又在原料上动起了心思。在很多人的观念中,进口的东西总是要比国产的好(插一句,很多洋品牌在华销售的质量啊、卫生等标准要比国际标准低的多,因为中国的标准要求本来就低,而且中国人心理承受能力强、好骗~)。商城原先的冰淇淋原料都是国产的,现在它决定把一部分产品的奶油用进口的奶油取代,进口奶油制作的冰淇淋价格稍高一些,顾客可以自行选择。
那么,商城应该怎样做呢?它当然可以再为每种口味的冰淇淋造一套相应的机器(用进口奶油来生产的机器,我们假设原先的机器是用国产奶油来生产的),也就是说仍然使用上面的“工厂方法模式”。可是,这样一来,商城就要新造原来一倍的机器(工厂类)了。倘若,商城是从原来的那一套切换到现在的生产国产、进口奶油冰淇淋的这一套,那么倒也没什么。毕竟,它只需要再加一些机器即可,不用做其它的改造。
倘若,商城一开始就规划了生产国产、进口奶油的冰淇淋呢?也就是说,它现在是第一次设计它的冰淇淋生产系统。那么,下面这样做也许更好:
1、国产奶油冰淇淋接口 ? DomesticIceCream.java
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?国产奶油冰淇淋接口?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?interface?DomesticIceCream?{??
-
????/**?
-
?????*?taste?方法?表明是哪种口味?
-
?????*/??
-
????public?void?taste();??
- }??
package com.abstractfactory.test;
/**
-
国产奶油冰淇淋接口
-
@author ThinkPad
*/
public interface DomesticIceCream {
/**
- taste 方法 表明是哪种口味
*/
public void taste();
}
2、进口奶油冰淇淋接口? ImportedIceCream.java
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?进口奶油冰淇淋接口?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?interface?ImportedIceCream?{??
-
????/**?
-
?????*?taste?方法?表明是哪种口味?
-
?????*/??
-
????public?void?taste();??
- }??
package com.abstractfactory.test;
/**
-
进口奶油冰淇淋接口
-
@author ThinkPad
*/
public interface ImportedIceCream {
/**
- taste 方法 表明是哪种口味
*/
public void taste();
}
3、苹果口味的冰淇淋(国产奶油)? AppleDomesticIceCream.java
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?苹果口味的冰淇淋(国产奶油)?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?AppleDomesticIceCream?implements?DomesticIceCream?{??
-
????@Override??
-
????public?void?taste()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????System.out.println(”苹果口味的冰淇淋(国产奶油)”);??
-
????}??
- }??
package com.abstractfactory.test;
/**
-
苹果口味的冰淇淋(国产奶油)
-
@author ThinkPad
*/
public class AppleDomesticIceCream implements DomesticIceCream {
@Override
public void taste() {
// TODO 自动生成的方法存根
System.out.println("苹果口味的冰淇淋(国产奶油)");
}
}
**
4、苹果口味的冰淇淋(进口奶油)? AppleImportedIceCream.java**
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?苹果口味的冰淇淋(进口奶油)?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?AppleImportedIceCream?implements?ImportedIceCream?{??
-
????@Override??
-
????public?void?taste()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????System.out.println(”苹果口味的冰淇淋(进口奶油)”);??
-
????}??
- }??
package com.abstractfactory.test;
/**
-
苹果口味的冰淇淋(进口奶油)
-
@author ThinkPad
*/
public class AppleImportedIceCream implements ImportedIceCream {
@Override
public void taste() {
// TODO 自动生成的方法存根
System.out.println("苹果口味的冰淇淋(进口奶油)");
}
}
5、香蕉口味的冰淇淋(国产奶油) ?BananaDomesticIceCream.java
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?香蕉口味的冰淇淋(国产奶油)?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?BananaDomesticIceCream?implements?DomesticIceCream?{??
-
????@Override??
-
????public?void?taste()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????System.out.println(”香蕉口味的冰淇淋(国产奶油)”);??
-
????}??
- }??
package com.abstractfactory.test;
/**
-
香蕉口味的冰淇淋(国产奶油)
-
@author ThinkPad
*/
public class BananaDomesticIceCream implements DomesticIceCream {
@Override
public void taste() {
// TODO 自动生成的方法存根
System.out.println("香蕉口味的冰淇淋(国产奶油)");
}
}
6、香蕉口味的冰淇淋(进口奶油) ?BananaImportedIceCream.java
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?香蕉口味的冰淇淋(进口奶油)?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?BananaImportedIceCream?implements?ImportedIceCream?{??
-
????@Override??
-
????public?void?taste()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????System.out.println(”香蕉口味的冰淇淋(进口奶油)”);??
-
????}??
- }??
package com.abstractfactory.test;
/**
-
香蕉口味的冰淇淋(进口奶油)
-
@author ThinkPad
*/
public class BananaImportedIceCream implements ImportedIceCream {
@Override
public void taste() {
// TODO 自动生成的方法存根
System.out.println("香蕉口味的冰淇淋(进口奶油)");
}
}
7、草莓口味的冰淇淋(国产奶油) ?StrawberryDomesticIceCream.java
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?草莓口味的冰淇淋(国产奶油)?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?StrawberryDomesticIceCream?implements?DomesticIceCream?{??
-
????@Override??
-
????public?void?taste()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????System.out.println(”草莓口味的冰淇淋(国产奶油)”);??
-
????}??
- }??
package com.abstractfactory.test;
/**
-
草莓口味的冰淇淋(国产奶油)
-
@author ThinkPad
*/
public class StrawberryDomesticIceCream implements DomesticIceCream {
@Override
public void taste() {
// TODO 自动生成的方法存根
System.out.println("草莓口味的冰淇淋(国产奶油)");
}
}
**
8、草莓口味的冰淇淋(进口奶油) StrawberryImportedIceCream.java**
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?草莓口味的冰淇淋(进口奶油)?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?StrawberryImportedIceCream?implements?ImportedIceCream?{??
-
????@Override??
-
????public?void?taste()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????System.out.println(”草莓口味的冰淇淋(进口奶油)”);??
-
????}??
- }??
package com.abstractfactory.test;
/**
-
草莓口味的冰淇淋(进口奶油)
-
@author ThinkPad
*/
public class StrawberryImportedIceCream implements ImportedIceCream {
@Override
public void taste() {
// TODO 自动生成的方法存根
System.out.println("草莓口味的冰淇淋(进口奶油)");
}
}
9、抽象的冰淇淋工厂类 ?IceCreamFactory.java
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?抽象的冰淇淋工厂类?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?abstract?class?IceCreamFactory?{??
-
????/**?
-
?????*?生产国产奶油冰淇淋?
-
?????*/??
-
????public?abstract?DomesticIceCream?produceDomesticIceCream();??
-
????/**?
-
?????*?生产进口奶油冰淇淋?
-
?????*/??
-
????public?abstract?ImportedIceCream?produceImportedIceCream();???
- }??
package com.abstractfactory.test;
/**
-
抽象的冰淇淋工厂类
-
@author ThinkPad
*/
public abstract class IceCreamFactory {
/**
- 生产国产奶油冰淇淋
*/
public abstract DomesticIceCream produceDomesticIceCream();
/**
- 生产进口奶油冰淇淋
*/
public abst
ract ImportedIceCream produceImportedIceCream();
}
10、苹果味冰淇淋工厂类 ? AppleIceCreamFactory.java
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?苹果味冰淇淋工厂类?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?AppleIceCreamFactory?extends?IceCreamFactory?{??
-
????@Override??
-
????public?DomesticIceCream?produceDomesticIceCream()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????return?new?AppleDomesticIceCream();??
-
????}??
-
????@Override??
-
????public?ImportedIceCream?produceImportedIceCream()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????return?new?AppleImportedIceCream();??
-
????}??
- }??
package com.abstractfactory.test;
/**
-
苹果味冰淇淋工厂类
-
@author ThinkPad
*/
public class AppleIceCreamFactory extends IceCreamFactory {
@Override
public DomesticIceCream produceDomesticIceCream() {
// TODO 自动生成的方法存根
return new AppleDomesticIceCream();
}
@Override
public ImportedIceCream produceImportedIceCream() {
// TODO 自动生成的方法存根
return new AppleImportedIceCream();
}
}
**
11、香蕉冰淇淋工厂类 ? BananaIceCreamFactory.java**
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?香蕉冰淇淋工厂类?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?BananaIceCreamFactory?extends?IceCreamFactory?{??
-
????@Override??
-
????public?DomesticIceCream?produceDomesticIceCream()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????return?new?BananaDomesticIceCream();??
-
????}??
-
????@Override??
-
????public?ImportedIceCream?produceImportedIceCream()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????return?new?BananaImportedIceCream();??
-
????}??
- }??
package com.abstractfactory.test;
/**
-
香蕉冰淇淋工厂类
-
@author ThinkPad
*/
public class BananaIceCreamFactory extends IceCreamFactory {
@Override
public DomesticIceCream produceDomesticIceCream() {
// TODO 自动生成的方法存根
return new BananaDomesticIceCream();
}
@Override
public ImportedIceCream produceImportedIceCream() {
// TODO 自动生成的方法存根
return new BananaImportedIceCream();
}
}
**
12、草莓冰淇淋工厂类 ? StrawberryIceCreamFactory.java**
[java] view plain copy
print ?
-
package?com.abstractfactory.test;??
-
/**?
-
?*?草莓冰淇淋工厂类?
-
?*?@author?ThinkPad?
-
?*?
-
?*/??
-
public?class?StrawberryIceCreamFactory?extends?IceCreamFactory?{??
-
????@Override??
-
????public?DomesticIceCream?produceDomesticIceCream()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????return?new?StrawberryDomesticIceCream();??
-
????}??
-
????@Override??
-
????public?ImportedIceCream?produceImportedIceCream()?{??
-
????????//?TODO?自动生成的方法存根??
-
????????return?new?StrawberryImportedIceCream();??
-
????}??
- }??
package com.abstractfactory.test;
/**
-
草莓冰淇淋工厂类
- @author ThinkPad