您好,登錄后才能下訂單哦!
文章首發
創建型模式:工廠方法
姓名:工廠方法
英文名:Factory method Pattern
價值觀:擴展是我的專屬
個人介紹:
Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses. (定義一個用于創建對象的接口,讓子類決定實例化哪一個類。工廠方法使一個類的實例化延遲到其子類。)
(來自《設計模式之禪》)
還記得上一篇 單例模式 中的故事么?小明開著汽車去旅游、去學校、去聚會。這一次還是延續小明的故事,一個故事能講 2 個設計模式,不容易呀。。。(每次想故事都想破腦袋,每一篇文章至少有 3 個故事從腦子里閃過,但最終留下的只有一個適合,為了就是能比較清晰簡單的說明設計模式中的關鍵要點。)
小明家里以前不算很富裕,但是還是有一個不錯的車庫,什么汽車、摩托車、自行車啥的都放在這個車庫里。小明每次要出去,都會到車庫里面挑合適的車出發。比如,小明最近期末考試了,騎摩托車去學校考試,考完試之后,小明就準備去旅游,這次決定自駕游,開著自己家的小汽車去。這個場景我們用代碼描述下。
public class SimpleFactoryTest {
public static void main(String[] args) {
XiaoMing xiaoMing = new XiaoMing();
// 小明騎摩托車去學校
IVehicle motorcycle = GarageFactory.getVehicle("motorcycle");
xiaoMing.goToSchool(motorcycle);
// 小明開汽車去旅游
IVehicle car = GarageFactory.getVehicle("car");
xiaoMing.travel(car);
}
}
/**
* 車庫
*/
class GarageFactory {
public static IVehicle getVehicle(String type) {
if ("car".equals(type)) {
return new Car();
} else if ("motorcycle".equals(type)) {
return new Motorcycle();
}
throw new IllegalArgumentException("請輸入車類型");
}
}
/**
* 交通工具
*/
interface IVehicle {
void run();
}
/**
* 汽車
*/
class Car implements IVehicle {
@Override
public void run() {
System.out.println("開汽車去。。。。");
}
}
/**
* 摩托車
*/
class Motorcycle implements IVehicle {
@Override
public void run() {
System.out.println("騎摩托車去。。。。");
}
}
class XiaoMing {
public void goToSchool(IVehicle vehicle) {
System.out.println("小明去學校");
vehicle.run();
}
public void travel(IVehicle vehicle) {
System.out.println("小明去旅游");
vehicle.run();
}
}
上面代碼看懂了么? 小明家里有一個車庫 GarageFactory,里面放著汽車 Car 和摩托車 Motorcycle,小明要出去的時候,就到車庫選擇車,通過傳遞參數給 GarageFactory.getVehicle(),指明要什么車,然后小明就騎著車出發了。
這個代碼真正的術語叫:簡單工廠模式(Simple Factory Pattern),也叫做靜態工廠模式。它是工廠方法中的一個實現方式,從字面理解就可以知道,它是最簡單的工廠方法實現方式。它有一點點小缺陷,就是擴展性不夠好,在上面代碼中,小明只能騎摩托車或者開汽車,如果小明要騎單車出去呢?勢必得在 GarageFactory 中添加 if 是自行車的邏輯。這違反了哪條規則了?是不是那個允許擴展,拒絕修改的開閉原則?
不是說簡單工廠這種實現方式不好,而是擴展性不夠,在平時的開發中,簡單工廠模式也用得不少。在這個小明家里車不多的情況下,用一個車庫也是合適的。
小明老爸近幾年賺了不少,車迷的兩父子一直買車,家里的車越來越多,這時候,他們決定多建幾個車庫,按車類型放置。比如,有一個汽車庫,一個摩托車庫。這時候小明要開汽車就去汽車庫,要騎摩托車就去摩托車庫。代碼實現如下。
public class FactoryMethodTest {
public static void main(String[] args) {
XiaoMing xiaoMing = new XiaoMing();
// 小明騎摩托車去學校
VehicleGarage motorcycleGarage = new MotorcycleGarage();
IVehicle motorcycle = motorcycleGarage.getVehicle();
xiaoMing.goToSchool(motorcycle);
// 小明開汽車去旅游
VehicleGarage carGarage = new CarGarage();
IVehicle car = carGarage.getVehicle();
xiaoMing.travel(car);
}
}
interface VehicleGarage {
IVehicle getVehicle();
}
/**
* 汽車車庫
*/
class CarGarage implements VehicleGarage {
@Override
public IVehicle getVehicle() {
return new Car();
}
}
/**
* 摩托車車庫
*/
class MotorcycleGarage implements VehicleGarage {
@Override
public IVehicle getVehicle() {
return new Motorcycle();
}
}
上面代碼重用了簡單工廠實現方式的交通接口以及摩托車和汽車的實現類。代碼中有 2 個車庫,一個是汽車車庫 CarGarage,一個是摩托車庫 MotorcycleGarage。如果小明要騎自行車,只需要建一個自行車車庫,完全不用去修改汽車車庫或者摩托車車庫,就非常符合開閉原則,擴展性大大的提高。
工廠方法模式可以說在你能想到的開源框架源碼中必定會使用的一個設計模式,因為開源框架很重要一點就是要有擴展性,而工廠方法模式恰恰具有可擴展性。弄懂了工廠方法模式,以后看開源代碼就很得心應手啦。
代碼鏈接:Factory method Pattern
推薦閱讀
單一職責原則(方法:修改名字還是密碼?接口:洗碗、買菜還是倒垃圾?類:注冊、登錄和注銷)
里氏替換原則(我兒來自新東方烹飪)
依賴倒置原則(摳門的飯店老板)
接口隔離原則(小伙子的作坊)
迪米特法則(手機上看電子書)
開閉原則(社保這點事)
創建型模式:單例模式(小明就只有 1 輛車)
公眾號后臺回復『大禮包』獲取 Java、Python、IOS 等教程
加個人微信備注『教程』獲取架構師、機器學習等教程
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。