关闭

简单工厂与工厂模式原理及案例分析

119人阅读 评论(0) 收藏 举报
分类:

  工厂方法的规范性定义描述为:工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

 

  在学习工厂方法前,我们应该先了解简单工厂这一种伪模式。之所以称之为伪模式,是因为严格意义上讲这并不算是一种模式,个人感觉更像是将某一功能抽象成了一个功能函数。

 

  编程的场景为:有一个专门生产果冻的生产商,可以生产出苹果、香蕉、橘子三种口味的果冻。如果现在该生产商被要求生产苹果口味的果冻,用简单工厂伪模式是如何编码的呢?

 

  首先,我们需要有果冻父类,并且根据不同口味的果冻定义出各种果冻的具体子类。这一层我称之为产品层:

 

  父类Jelly表现为:


public abstract class Jelly {  
  
    String name;             //果冻名称  
    String fruitMaterial;   //果冻的材料  
    String pigment;          //染色  
  
    public void prepare(){  
        System.out.println("The jelly's name is "+name);  
        System.out.println("The jelly's fruitMaterial is "+fruitMaterial);  
        System.out.println("The jelly's pigment is "+pigment);  
    }  
  
    public void melt(){  
        System.out.println("melt the material");  
    }  
    public void put(){  
        System.out.println("put the fruit");  
    }  
    public void cold(){  
        System.out.println("cold the material");  
    }  
    public void box(){  
        System.out.println("put the jelly into boxes");  
    }  
  
    public String getName() {  
        return name;  
    }  
}

 以下是三种口味果冻的子类:

         

public class AppleJetty extends Jelly{  
  
    public AppleJetty() {  
        this.name = "appleJetty";  
        this.fruitMaterial = "apple";  
        this.pigment = "no";  
    }  
  
    @Override  
    public void put(){  
        System.out.println("put the apple");  
    }  
}  
  
  
public class BananaJetty extends Jelly{  
  
    public BananaJetty() {  
        this.name = "bananaJetty";  
        this.fruitMaterial = "banana";  
        this.pigment = "no";  
    }  
  
    @Override  
    public void put(){  
        System.out.println("put the banana");  
    }  
}  
  
  
public class OrangeJetty extends Jelly{  
  
    public OrangeJetty() {  
        this.name = "orangeJetty";  
        this.fruitMaterial = "orange";  
        this.pigment = "no";  
    }  
  
    @Override  
    public void put(){  
        System.out.println("put the orange");  
    }  
}

  产品层到此为止,接下来就需要工厂层来生产产品。这里用JellyCompany类来表示


public class JellyCompany {  
  
    SimpleJettyFactory simpleJettyFactory;  
  
    public JellyCompany(SimpleJettyFactory simpleJettyFactory) {  
        this.simpleJettyFactory = simpleJettyFactory;  
    }  
  
    public Jelly orderJelly(String type){  
        Jelly jelly;  
        jelly = simpleJettyFactory.createJetty(type);  
  
        jelly.prepare();  
        jelly.melt();  
        jelly.put();  
        jelly.cold();  
        jelly.box();  
  
        return jelly;  
    }  
}


  此时JellyCompany类里面的SimpleJettyFactory就是像抽象出来的功能函数。它的具体实现为:


public class SimpleJettyFactory {  
    public Jelly createJetty(String type){  
        Jelly jelly = null;  
  
        if(type.equals("appleJetty")){  
            jelly = new AppleJetty();  
        }else if(type.equals("orangeJetty")){  
            jelly = new OrangeJetty();  
        }else if(type.equals("bananaJetty")){  
            jelly = new BananaJetty();  
        }  
  
        return jelly;  
    }  
}

  最后就是运行类SimpleFactorySimulator:


public class SimpleFactorySimulator {  
    public static void main(String[] args){  
  
        SimpleJettyFactory simpleJettyFactory = new SimpleJettyFactory();  
        JellyCompany jellyCompany = new JellyCompany(simpleJettyFactory);  
        Jelly jelly = jellyCompany.orderJelly("appleJetty");  
        System.out.println("该公司已生产 "+jelly.getName());  
    }  
}

  输出结果为:


The jelly's name is appleJetty  
The jelly's fruitMaterial is apple  
The jelly's pigment is no  
melt the material  
put the apple  
cold the material  
put the jelly into boxes  
该公司已生产 appleJetty

  但是与上面只是抽出功能函数的简单工厂比较,工厂模式则更适于变化。现在如果该公司成立了一个分公司:上海分公司(这里默认该公司的总部在北京)。但是由于地域性饮食差异,这使得两个不同地方的公司生产的果冻流程有一些差异:北京总公司生产的果冻,其中的果肉倾向于更多更大,而上海分公司的果冻则更倾向于多放糖。如果某客户要求生产北京的苹果果冻和上海的橘子果冻,那么简单工厂很明显已经不适应这种多变化需要。这时候我们来研究一下工厂模式:
  同样的,先列出model层,果冻父类Jelly为:
public abstract class Jelly {  
  
    String name;  
    String fruitMaterial;  
    String pigment;  
  
    public void prepare(){  
        System.out.println("The jelly's name is "+name);  
        System.out.println("The jelly's fruitMaterial is "+fruitMaterial);  
        System.out.println("The jelly's pigment is "+pigment);  
    }  
  
    public void melt(){  
        System.out.println("melt the material");  
    }  
    public void put(){  
        System.out.println("put the fruit");  
    }  
    public void cold(){  
        System.out.println("cold the material");  
    }  
    public void box(){  
        System.out.println("put the jelly into boxes");  
    }  
  
    public String getName() {  
        return name;  
    }  
  
}

  下面依次是上海分公司所能生产的三种果冻:


public class ShanghaiAppleJelly extends Jelly{  
  
    public ShanghaiAppleJelly() {  
        this.name = "ShanghaiAppleJetty";  
        this.fruitMaterial = "apple";  
        this.pigment = "no";  
    }  
  
    @Override  
    public void put(){  
        System.out.println("put the apple and lots of sugar");  
    }  
}  
  
  
public class ShanghaiBananaJelly extends Jelly{  
  
    public ShanghaiBananaJelly() {  
        this.name = "ShanghaiBananaJetty";  
        this.fruitMaterial = "banana";  
        this.pigment = "no";  
    }  
  
    @Override  
    public void put(){  
        System.out.println("put the banana and lots of sugar");  
    }  
}  
  
  
public class ShanghaiOrangeJelly extends Jelly{  
  
    public ShanghaiOrangeJelly() {  
        this.name = "ShanghaiOrangeJetty";  
        this.fruitMaterial = "orange";  
        this.pigment = "no";  
    }  
  
    @Override  
    public void put(){  
        System.out.println("put the orange and lots of sugar");  
    }  
}

  北京总公司所能生产的三种果冻:


public class BeijingAppleJelly extends Jelly {  
  
    public BeijingAppleJelly() {  
        this.name = "BeijingAppleJelly";  
        this.fruitMaterial = "apple";  
        this.pigment = "no";  
    }  
  
    @Override  
    public void put(){  
        System.out.println("put the apple and cut into large pieces");  
    }  
}  
  
  
public class BeijingBananaJelly extends Jelly{  
  
    public BeijingBananaJelly() {  
        this.name = "BeijingBananaJetty";  
        this.fruitMaterial = "banana";  
        this.pigment = "no";  
    }  
  
    @Override  
    public void put(){  
        System.out.println("put the banana and cut into large pieces");  
    }  
}  
  
  
public class BeijingOrangeJelly extends Jelly{  
  
    public BeijingOrangeJelly() {  
        this.name = "BeijingOrangeJetty";  
        this.fruitMaterial = "orange";  
        this.pigment = "no";  
    }  
  
    @Override  
    public void put(){  
        System.out.println("put the orange and cut into large pieces");  
    }  
}

  下面是工厂层:抽象父类JellyCompany


public abstract class JellyCompany {  
  
    public Jelly orderJelly(String type){  
        Jelly jelly;  
        jelly = createJelly(type);   //注意此处将实例化延迟到了实现子类  
  
        jelly.prepare();  
        jelly.melt();  
        jelly.put();  
        jelly.cold();  
        jelly.box();  
  
        return jelly;  
    }  
  
    abstract Jelly createJelly(String type);  
}

  北京总公司实现子类与上海子公司实现子类


public class BeijingJellyCompany extends JellyCompany {  
  
    Jelly createJelly(String type){  
        if(type.equals("appleJelly")){  
            return new BeijingAppleJelly();   //因为是北京公司,所以采用生产北京果冻的生成方法  
        }else if(type.equals("orangeJelly")){  
            return new BeijingOrangeJelly();  
        }else if(type.equals("bananaJelly")){  
            return new BeijingBananaJelly();  
        }else  
            return null;  
    }  
}  
  
public class ShanghaiJellyCompany extends JellyCompany {  
  
    Jelly createJelly(String type){  
        if(type.equals("appleJelly")){  
            return new ShanghaiAppleJelly();  
        }else if(type.equals("orangeJelly")){  
            return new ShanghaiOrangeJelly();  
        }else if(type.equals("bananaJelly")){  
            return new ShanghaiBananaJelly();  
        }else  
            return null;  
    }  
}

  最后是运行类JellySimulator:


public class JellySimulator {  
  
    public static void main(String[] agrs){  
        JellyCompany beijingJellyComyany = new BeijingJellyCompany();  
        JellyCompany shanghaiJellyComyany = new ShanghaiJellyCompany();  
  
        Jelly jelly = beijingJellyComyany.orderJelly("appleJelly");  
        System.out.println("BeijingJelly : "+jelly.getName());  
  
        System.out.println("==================");  
  
        jelly = shanghaiJellyComyany.orderJelly("orangeJelly");  
        System.out.println("ShanghaiJelly : "+jelly.getName());  
    }  
}

  运行结果为:


The jelly's name is BeijingAppleJelly  
The jelly's fruitMaterial is apple  
The jelly's pigment is no  
melt the material  
put the apple and cut into large pieces  
cold the material  
put the jelly into boxes  
BeijingJelly : BeijingAppleJelly  
==================  
The jelly's name is ShanghaiOrangeJetty  
The jelly's fruitMaterial is orange  
The jelly's pigment is no  
melt the material  
put the orange and lots of sugar  
cold the material  
put the jelly into boxes  
ShanghaiJelly : ShanghaiOrangeJetty

  通过上面的两个例子大家可以比较一下简单工厂与工厂模式的区别:简单工厂更像是抽象出一个功能函数,而工厂模式则是抽象父类定义好一系列完整流程,而具体生产什么样产品的实例化交给子类去做。就变化的适应性而言,工厂模式更为优秀。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:913次
    • 积分:75
    • 等级:
    • 排名:千里之外
    • 原创:7篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档