qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

抽象工厂模式

public interface IMobilePhone {
    
public void call();
}

public class NokiaMPhone implements IMobilePhone{
    
public void call(){
    }
}

public class OppoMPhone implements IMobilePhone{
    
public void call(){
    }
}

public interface IFactory {
    
public IMobilePhone createNokiaPhone();
    
public IMobilePhone createOppoPhone();
}

public class MobilePhoneFactory implements IFactory{
    
public IMobilePhone createNokiaPhone(){
        
return new NokiaMPhone();
    }
    
public IMobilePhone createOppoPhone(){
        
return new OppoMPhone();
    }
}

public class Client {
    
public static void main(String args[]){
        IFactory factory 
= new MobilePhoneFactory();
        IMobilePhone nokia 
= factory.createNokiaPhone();
        IMobilePhone oppo 
= factory.createOppoPhone();
        nokia.call();
        oppo.call();
    }
}

就代码上而言,工厂模式和抽象工厂模式功能上是差不多的。都通过借口遍程实现了比较好的代码隔离。不同的地方在于factory类的组织。工厂模式对每一个产品均实现一个工厂。而抽象工厂在一个工厂类中建立多个方法返回多种产品。

本实例需要根据植物园的种类确定植物园的布局, 而植物园的种类有很多,对应的植物园布局也各不相同。在这里假设有3种植物园:蔬菜园,一年生植物园,多年生植物园。这3garden中种植的植物各不相同,体现在程序中即返回不同的关于“植物园布局”的对象。生成植物园的布局是我们的目的,如果把蔬菜园、一年生植物园、多年生植物园看作是3个“产品族”,而某一时刻只需要其中一个产品族。由于每个产品族需要一个生产的工厂,所以生产这3个产品族需要3个工厂,分别是蔬菜园工厂(VegieGarden.java),一年生植物园工厂(AnnualGarden.java),多年生植物园工厂(PerennialGarden.java)。由于这3个工厂都是生产植物园的工厂,每个工厂生产的产品又基本相同(都生产“中心布局”、“边沿布局”、“阴处布局”3个产品),所以可以抽象一个工厂类(Garden.java),这个工厂类也具备生产“中心布局”、“边沿布局”和“阴处布局”3个产品的能力,而生产的方法由具体的工厂来实现。这样,再通过一个总控程序(GardenMaker.java)(这个总控程序也可以放到抽象的工厂中)指定需要调用的具体工厂。

首先来创建Plant.java类,它只有一个name属性

public class Plant {
    String name;

    
public Plant(String name) {        
        
this.name = name;
    }

    
public String getName() {
        
return name;
    }
}


然后是Garden类,3个方法分别是得到中心处、边沿处和阴暗处的植物

public abstract class Garden {
    
public abstract Plant getCenter();
    
public abstract Plant getBorder();
    
public abstract Plant getShade();
}

下面是3个工厂类
/**
 * 一年生植物园工厂
 * 
@author Heinvo Lee
 *
 
*/
public class AnnualGarden extends Garden {

    @Override
    
public Plant getCenter() {
        
// TODO Auto-generated method stub
        return new Plant("Marigold");//万寿菊
    }
    
    @Override
    
public Plant getBorder() {
        
// TODO Auto-generated method stub
        return new Plant("Alyssum");//十字花科植物;庭荠
    }

    @Override
    
public Plant getShade() {
        
// TODO Auto-generated method stub
        return new Plant("Coleus");//薄荷科植物
    }

}

/**
 * 常年生植物园工厂
 * 
@author Heinvo Lee
 *
 
*/
public class PerennialGarden extends Garden {



    @Override
    
public Plant getCenter() {
        
// TODO Auto-generated method stub
        return new Plant("Dicentrum");
    }
    
    @Override
    
public Plant getBorder() {
        
// TODO Auto-generated method stub
        return new Plant("Sedum");//景天属植物;八宝
    }

    @Override
    
public Plant getShade() {
        
// TODO Auto-generated method stub
        return new Plant("Astilbe");//落新妇属植物
    }

}

/**
 * 蔬菜园工厂
 * 
@author Heinvo Lee
 *
 
*/
public class VegieGarden extends Garden {

    
public Plant getCenter() {
        
return new Plant("Corn");
        }
    
public Plant getBorder() {
        
return new Plant("Peas");
        }
    
    
public Plant getShade() {        
        
return new Plant("Broccoli");//花椰菜
        }

}

接下来创建总控类GardenMaker
public class GardenMaker {
    
private Garden garden;
    
public Garden getGarden(String gtype)
    {
        garden 
= new VegieGarden(); //default
    if(gtype.equals("Perennial"))
        garden 
= new PerennialGarden();
    
if(gtype.equals("Annual"))
        garden 
= new AnnualGarden();
    
return garden;
    }
}

然后是一个测试类了
public class Main {

    
/**
     * 
@param args
     
*/
    
public static void main(String[] args) {
        GardenMaker gm
=new GardenMaker();
        Garden vg
=gm.getGarden("Vegie");
        Garden ag
=gm.getGarden("Annual");
        Garden pg
=gm.getGarden("Perennial");
        
        System.out.println(
"Vegie garden, center: "+vg.getCenter().getName());
        System.out.println(
"Vegie garden, border: "+vg.getBorder().getName());
        System.out.println(
"Vegie garden, shade: "+vg.getShade().getName());
        System.out.println(
"------------------------------------");
        System.out.println(
"Annual garden, center: "+ag.getCenter().getName());
        System.out.println(
"Annual garden, border: "+ag.getBorder().getName());
        System.out.println(
"Annual garden, shade: "+ag.getShade().getName());
        System.out.println(
"------------------------------------");
        System.out.println(
"Perennial garden, center: "+pg.getCenter().getName());
        System.out.println(
"Perennial garden, border: "+pg.getBorder().getName());
        System.out.println(
"Perennial garden, shade: "+pg.getShade().getName());
        
        
// TODO Auto-generated method stub

    }

}

执行这个测试类,可以在控制台看到以下效果(我以红色标红)

Vegie garden, center: Corn
Vegie garden, border: Peas
Vegie garden, shade: Broccoli
------------------------------------
Annual garden, center: Marigold
Annual garden, border: Alyssum
Annual garden, shade: Coleus
------------------------------------
Perennial garden, center: Dicentrum
Perennial garden, border: Sedum
Perennial garden, shade: Astilbe

从这个例子我看出以下:
  GardenMaker gm=new GardenMaker();
  Garden vg=gm.getGarden("Vegie");
  Garden ag=gm.getGarden("Annual");
  Garden pg=gm.getGarden("Perennial");
上面4句代码是测试类里面的

当需要生产某一种植物园的布局时,只需要将植物园的类型告诉总控程序(GardenMaker.java),这里是传入参数Vegie、Annual、Perennial,总控程序决定使用生产指定类型植物园的工厂生产出需要的“产品族”,而在此过程中,不需要了解具体工厂中的方法是如何实现的。

posted on 2011-09-26 11:06 顺其自然EVO 阅读(190) 评论(0)  编辑  收藏

<2011年9月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜