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();
}
抽象工廠模式的優點在於封裝性比較好,以接口的形式提供,不需要知道具體如何實現,全部由工廠類來負責創造。所有的約束條件在工廠內實現,不對外公開。只需要知道是哪個工廠就可以創造出想要的對象。
缺點在於產品族非常難以擴展,例如,如果需要增加一個顏色或半生不熟的產品族。那麼代碼不滿足通用原則,需要全部修改,但是如果增加一個產品,比如麪包,這樣直接新添加一個麪包工廠即可。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.