java設計模式一工廠模式

工廠模式

描述:
  • 定義一個創建對象的接口,讓其子類自己決定實例化哪一個工廠類,工廠模式使其創建過程延遲到子類進行。
使用場景:
  • 消費者不關心它所要創建對象的類(產品類)的時候。
  • 消費者知道它所要創建對象的類(產品類),但不關心如何創建的時候···等等。
  • 應用場景舉例:
    1、您需要一輛汽車,可以直接從工廠裏面提貨,而不用去管這輛汽車是怎麼做出來的,以及這個汽車裏面的具體實現。
    2、日誌記錄器:記錄可能記錄到本地硬盤、系統事件、遠程服務器等,用戶可以選擇記錄日誌到什麼地方。
    3、數據庫訪問,當用戶不知道最後系統採用哪一類數據庫,以及數據庫可能有變化時。
優點:
  • 一個調用者想創建一個對象,只要知道其名稱就可以了。
  • 擴展性高,如果想增加一個產品,只要擴展一個工廠類就可以。
  • 屏蔽產品的具體實現,調用者只關心產品的接口。
缺點:
  • 每次增加一個產品時,都需要增加一個具體類和對象實現工廠,使得系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,同時也增加了系統具體類的依賴。

一、簡單工廠模式(靜態工廠模式)

例子如下:

Animal類:

package com.bean;  
/** 
 * 動物類 
 * @author Lyon Yao 
 * 
 */  
public abstract class Animal {  

    private String name;  

    public Animal() {  
        super();  
        // TODO Auto-generated constructor stub  
    }  
    public Animal(String name) {  
        super();  
        this.name = name;  
    }  
    public abstract void eat();  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  

}  

貓類:

package com.bean;  

/** 
 * 貓類 
 * @author Lyon Yao 
 * 
 */  
public class Cat extends Animal {  

    public Cat() {  
        // TODO Auto-generated constructor stub  
    }  

    public Cat(String name) {  
        super(name);  
        // TODO Auto-generated constructor stub  
    }  

    @Override  
    public void eat() {  
        // TODO Auto-generated method stub  
        System.out.println("I like to eat fish!");  
    }  

}  

狗類:

/** 
 * 狗類 
 * @author Lyon Yao 
 * 
 */  
public class Dog extends Animal {  

    public Dog() {  
        // TODO Auto-generated constructor stub  
    }  

    public Dog(String name) {  
        super(name);  
        // TODO Auto-generated constructor stub  
    }  

    @Override  
    public void eat() {  
        // TODO Auto-generated method stub  
        System.out.println("I like to eat bone!");  
    }  

}  

靜態工廠類:

package com.factory.sta;  

import java.lang.reflect.Constructor;  
import java.lang.reflect.InvocationTargetException;  

/** 
 * 靜態工廠創建一個對象  靜態工廠類產生的對象一般都有共同的特性,繼承某一類,或者引用接口之類,在此 
 * 沒有看似沒有,但不可否認他們都是Object或者Object的一個子類 
 * @author Lyon Yao 
 * 
 */  
public class StaticFatory {  
    public static Object getInstance(String className){  
        Object instance=null;  
        try {  
            Class cls=Class.forName(className);  
            instance= cls.newInstance();  
        } catch (ClassNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (InstantiationException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IllegalAccessException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        return instance;  

    }  
    public static Object getInstance(String className,Object ...agrs) {  
        Class cls=null;  
        try {  
            cls = Class.forName(className);  
        } catch (ClassNotFoundException e1) {  
            // TODO Auto-generated catch block  
            return null;  
        }  
        Constructor[] constructors = cls.getConstructors();  
        Object instance=null;  
        for(Constructor cons:constructors){  
            Class <?>[] clses=cons.getParameterTypes();  
            if(clses.length>0){  
                boolean isThisConstructor=true;  
                for(int i=0;i<clses.length;i++){  
                    Class c=clses[i];   
                    if(! c.isInstance(agrs[i]) ){  
                        isThisConstructor=false;  
                    }  
                }  
                if(isThisConstructor){  
                    try {  
                        instance=cons.newInstance(agrs);  
                        break;  
                    } catch (IllegalArgumentException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    } catch (InvocationTargetException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    } catch (InstantiationException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    } catch (IllegalAccessException e) {  
                        // TODO Auto-generated catch block  
                        e.printStackTrace();  
                    }  
                }else{  
                    continue;  
                }  

            }  
        }  
        return instance;  
    }  
}  

二、工廠方法模式:

  • 其主要是對各個類型的東西分類生產,但分類生產的對象仍然是具有某一特性的。譬如說:前面的靜態工廠類是一個綜合造車工廠,不管是汽車還是火車都能生產,而工廠方法模式就是工廠具體分工,造汽車的工廠只造汽車,造火車的只造火車,不管造汽車還是火車但造出來的還是車。

  • 具體代碼例子如下:(這裏的例子和上面的例子是一起的,狗生好多小狗,貓生好多小貓的例子,如果不具體那麼是母動物都能生的)

母動物接口:

package com.factory;  

import com.bean.Animal;  

/** 
 * 母親接口 
 * @author Lyon 
 * 
 */  
public interface AnimalMother {  
    /** 
     * 生育動物 
     * @return 
     */  
    public  Animal giveBirth();  
}  

母狗類:

package com.factory.impl;  

import com.bean.Animal;  
import com.bean.Dog;  
import com.factory.AnimalMother;  

/** 
 * 狗母親  生狗 
 * @author Lyon Yao 
 * 
 */  
public class DogMother implements AnimalMother {  

    @Override  
    public Animal giveBirth() {  
        // TODO Auto-generated method stub  
        Animal dog=new Dog();  
        System.out.println("狗母親生了一隻小狗");  
        return dog;  
    }  

}  

母貓類:

package com.factory.impl;  

import com.bean.Animal;  
import com.bean.Cat;  
import com.factory.AnimalMother;  

/** 
 * 貓母親 生貓咪 
 * @author Lyon Yao 
 * 
 */  
public class CatMother implements AnimalMother {  

    @Override  
    public Animal giveBirth() {  
        // TODO Auto-generated method stub  
        Animal cat=new Cat();  
        System.out.println("貓母親生了一隻小貓眯");  
        return cat;  
    }  

}  

三、抽象工廠模式:

  • 前面工廠方法模式是比較具體的,是貓肯定生的是小貓,這是不會有問題的,是具體的,那麼抽象工廠它所產生的就不是那麼具體,產生的對象可能是沒有共同特性的。譬如說 一隻奶羊不僅僅能夠生小羊,同時也能生產羊奶,但小羊是動物,羊奶是食物。

例子如下:

總工廠:

package com.factory;  

import com.bean.Milk;  

/** 
 * 能產奶的 動物母親 
 * 這裏繼承 AnimalMother 實現 生育小動物  產奶在此接口聲明 構成抽象工廠總接口 
 * @author Lyon Yao 
 * 
 */  
public interface MilkAnimalMother extends AnimalMother {  
    /** 
     * 產奶 
     * @return 
     */  
    public Milk produceMilk();  
}  

奶羊:

package com.factory.impl;  

import com.bean.Animal;  
import com.bean.Milk;  
import com.bean.Sheep;  
import com.bean.SheepMilk;  
import com.factory.MilkAnimalMother;  

/** 
 * 奶羊 
 * @author Lyon Yao 
 * 
 */  
public class SheepMilkMother implements MilkAnimalMother{  

    @Override  
    public Animal giveBirth() {  
        // TODO Auto-generated method stub  
        Animal sheep=new Sheep();  
        System.out.println("奶羊生了一隻小羊");  
        return sheep;  
    }  

    @Override  
    public Milk produceMilk() {  
        // TODO Auto-generated method stub  
        Milk milk=new SheepMilk();  
        System.out.println("奶羊生產了羊奶");  
        return milk;  
    }  

}  

奶牛:

 package com.factory.impl;  

import com.bean.Animal;  
import com.bean.Cattle;  
import com.bean.CattleMile;  
import com.bean.Milk;  
import com.factory.MilkAnimalMother;  

/** 
 * 奶牛() 
 * @author Lyon Yao 
 * 
 */  
public class CattleMilkMother implements MilkAnimalMother {  

    @Override  
    public Animal giveBirth() {  
        // TODO Auto-generated method stub  
        Cattle cattle=new Cattle();  
        System.out.println("奶牛生了一隻小牛");  
        return cattle;  
    }  

    @Override  
    public Milk produceMilk() {  
        // TODO Auto-generated method stub  
        Milk milk=new CattleMile();  
        System.out.println("奶牛生產了牛奶");  
        return milk;  
    }  
}  

下面是測試例子:

package com.test;  

import org.junit.Test;  

import com.bean.Animal;  
import com.bean.Cat;  
import com.bean.Dog;  
import com.factory.AnimalMother;  
import com.factory.MilkAnimalMother;  
import com.factory.impl.CatMother;  
import com.factory.impl.CattleMilkMother;  
import com.factory.impl.DogMother;  
import com.factory.impl.SheepMilkMother;  
import com.factory.sta.StaticFatory;  

/** 
 * 測試類 
 *  
 * @author Lyon Yao 
 *  
 */  
public class TestCase {  
    /** 
     * 靜態工廠類 測試 
     */  
    @Test  
    public void staticFactoryTest() {  
        Animal ani1=(Animal) StaticFatory.getInstance(Cat.class.getName());  
        System.out.println(ani1.getName());  
        ani1.eat();  
        ani1=(Animal) StaticFatory.getInstance(Dog.class.getName(),"dog");  
        System.out.println(ani1.getName());  
        ani1.eat();  
    }  
    /** 
     * 工廠方法模式測試 
     */  
    @Test  
    public void methodFactoryTest(){  
        AnimalMother mother=new CatMother();  
        mother.giveBirth();  
        mother=new DogMother();  
        mother.giveBirth();  
    }  
    /** 
     * 抽象工廠模式測試 
     */  
    @Test  
    public void abstrFactoryTest(){  
        MilkAnimalMother mother=new SheepMilkMother();  
        mother.giveBirth();  
        mother.produceMilk();  
        mother=new CattleMilkMother();  
        mother.giveBirth();  
        mother.produceMilk();  
    }  
}  

控制檯輸出:

null

I like to eat fish!

dog

I like to eat bone!

貓母親生了一隻小貓眯

狗母親生了一隻小狗

奶羊生了一隻小羊

奶羊生產了羊奶

奶牛生了一隻小牛

奶牛生產了牛奶
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章