JAVA設計模式【一】 - 簡單工廠模式、工廠方法模式、抽象工廠模式

 
簡單工廠模式(靜態工廠模式)
 
     普通工廠模式就是創建一個工廠類,創建並返回多個實現相同接口的類的實例。
例子:根據傳遞的類型生產不同的食物。
     有一個生產食物的接口:
/**
* Created by j on 2018/2/27.
*/
public interface Food {
    
    public static void creatFood();
 
}
  
   一個生產麪條的實現類:
    
/**
* Created by j on 2018/2/27.
*/
public class Noodle implements Food {
 
    public static void creatFood() {
        System.out.println("生產麪條");
    }
}
 
    一個生產大米的實現類:
/**
* Created by j on 2018/2/27.
*/
public class Rice implements Food {
    @Override
    public static void creatFood() {
        System.out.println("生產大米");
    }
}
 
 
 
  創建一個食物工廠:
/**
* Created by j on 2018/2/27.
*/
public class FoodFactory {
 
    public static Food getFood(String type) {
        if ("noodle".equals(type)) {
            return new Noodle();
        } else if ("rice".equals(type)) {
            return new Rice();
        } else {
            throw new NullPointerException("找不到需要的類型");
        }
    }
}
 
    最後創建一個測試類:
    
/**
* Created by kaijiyu on 2018/2/27.
*/
public class Test {
 
    public static void main(String[] args) {
        Food food = FoodFactory.getFood("noodle");
        food.creatFood();
    }
 
}
 
其實這樣做的缺點很明顯,雖然能夠根據類型對應返回不同的實例,但是如果新加一個品種比如麪包,就需要修改工廠類,違反了開閉原則,不利於維護。
 
工廠方法模式
    
    工廠方法模式是對簡單工廠模式的升級,將工廠抽象出來,對每個產品創建一個工廠來專門生產,使其可以擴展,複合開閉原則。
 
    
食物類:
/**
* Created by j on 2018/2/28.
*/
public interface Food {
 
    public void getFoodName();
 
}
 
/**
* Created by j on 2018/2/28.
*/
public class Noodle implements Food {
 
    @Override
    public void getFoodName() {
        System.out.println("食物的名稱是麪條");
    }
 
}
 
/**
* Created by j on 2018/2/28.
*/
public class Rice implements Food {
 
    @Override
    public void getFoodName() {
        System.out.println("食物的名稱是大米");
    }
 
}
 
工廠類:
/**
* Created by j on 2018/2/28.
*/
public interface FoodFactory {
 
    public Food createFood();
}
 
/**
* Created by j on 2018/2/28.
*/
public class NoodleFactory implements FoodFactory {
    @Override
    public Food createFood() {
        return new Noodle();
    }
}
 
/**
* Created by j on 2018/2/28.
*/
public class RiceFactory implements FoodFactory {
    @Override
    public Food createFood() {
        return new Rice();
    }
}
 
測試類:
/**
* Created by j on 2018/2/28.
*/
public class Test {
    public static void main(String[] args) {
        FoodFactory noodleFactory = new NoodleFactory();
        FoodFactory riceFactory = new RiceFactory();
        Food noodle = noodleFactory.createFood();
        Food rice = riceFactory.createFood();
        noodle.getFoodName();
        rice.getFoodName();
    }
}
 
工廠方法模式是對一種產品族的多種產品的生產,如果對於多產品族,比如說食物添加一個產品族,分成生的和熟的,這時代碼就無法進行通用了。這時,就需要用到抽象工廠模式
 
抽象工廠模式
抽象工廠是工廠方法模式的升級版,用於多產品族多種產品的情況使用。
 
食物類:
 
public interface Food {
 
    public void getFoodName();
 
    public void getIsCooked();
 
}
 
public abstract class CookedFood implements Food{
    public void getIsCooked(){
        System.out.println("生產一個熟的食物");
    }
}
 
public abstract class RawFood implements Food{
    public void getIsCooked(){
        System.out.println("生產一個生的食物");
    }
}
 
public class CookedNoodle extends CookedFood {
 
    @Override
    public void getFoodName() {
        System.out.println("食物的名稱是麪條");
    }
 
}
 
public class CookedRice extends CookedFood {
 
    @Override
    public void getFoodName() {
        System.out.println("食物的名稱是大米");
    }
 
}
 
public class RawNoodle extends RawFood {
 
    @Override
    public void getFoodName() {
        System.out.println("食物的名稱是麪條");
    }
 
}
 
public class RawRice extends RawFood {
 
    @Override
    public void getFoodName() {
        System.out.println("食物的名稱是大米");
    }
 
}
 
工廠類:
public interface FoodFactory {
 
    public Food createCookedFood();
    public Food createRawFood();
 
}
 
public class NoodleFactory implements FoodFactory {
 
    @Override
    public CookedFood createCookedFood() {
        return new CookedNoodle();
    }
 
    @Override
    public Food createRawFood() {
        return new RawNoodle();
    }
}
 
public class RiceFactory implements FoodFactory {
 
    @Override
    public Food createCookedFood() {
        return new CookedRice();
    }
 
    @Override
    public Food createRawFood() {
        return new RawRice();
    }
}
 
測試類:
public class Test {
    public static void main(String[] args) {
        FoodFactory noodleFactory = new NoodleFactory();
        FoodFactory riceFactory = new RiceFactory();
        // 生產一個熟的麪條
        Food noodle = noodleFactory.createCookedFood();
        // 生產一個生的大米
        Food rice = riceFactory.createRawFood();
 
        noodle.getIsCooked();
        noodle.getFoodName();
 
        rice.getIsCooked();
        rice.getFoodName();
    }
}
 
也可以通過反射的機制和簡單工廠模式來將抽象工廠升級:
public class AbsFoodFactory {
    // 通過AbsFoodFactory.createFood(CookedNoodle.class); 調用
    public static Food createFood(Class clazz) throws Exception {
        return (Food)clazz.newInstance();
}
 
 
抽象工廠模式的優點在於封裝性比較好,以接口的形式提供,不需要知道具體如何實現,全部由工廠類來負責創造。所有的約束條件在工廠內實現,不對外公開。只需要知道是哪個工廠就可以創造出想要的對象。
 
缺點在於產品族非常難以擴展,例如,如果需要增加一個顏色或半生不熟的產品族。那麼代碼不滿足通用原則,需要全部修改,但是如果增加一個產品,比如麪包,這樣直接新添加一個麪包工廠即可。

 

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