一、
製作一個抽象產品:螺絲
製作2個具體產品:8mm螺絲 和 6mm螺絲
使用簡單工廠來實現這個場景,並且讓客戶端通過簡單工廠來獲取具體產品。
然後擴展一個7mm螺絲,你會發現這要修改簡單工廠的代碼。進而違反了開閉原則。
所以在使用工廠方法來重構一遍代碼。保證7mm螺絲可以被順利地擴展進來
簡單工廠
/**
* @author 鄭金衝
* @create 2020-05-29 20:29
* @Description 簡單工廠 作業
* @Telephone 17805202282
* @Email [email protected]
*/
public class Client {
public static void main(String[] args) {
Factory.getScrew("8毫米").screwInfourmation();
}
}
//產品基類: 螺絲
interface Screw {
public void screwInfourmation();
}
//具體產品類: 8毫米螺絲
class EightMillimeterScrew implements Screw {
@Override
public void screwInfourmation() {
System.out.println("我是一個8毫米的螺絲啊。。。。");
}
}
//具體產品類: 6毫米螺絲
class SixMillimeterScrew implements Screw {
@Override
public void screwInfourmation() {
System.out.println("我是一個6毫米的螺絲啊。。。。");
}
}
//工廠
class Factory {
public static Screw getScrew(String type) {
Screw screw = null;
switch (type) {
case "8毫米":
screw = new EightMillimeterScrew();
break;
case "6毫米":
screw = new SixMillimeterScrew();
break;
}
return screw;
}
}
工廠方法
/**
* @author 鄭金衝
* @create 2020-05-29 20:29
* @Description 簡單工廠 作業
* @Telephone 17805202282
* @Email [email protected]
*/
public class Client2 {
public static void main(String[] args) {
SevenMillimeterScrewFactory obj = new SevenMillimeterScrewFactory();
obj.getScrew().screwInfourmation();
}
}
//產品基類: 螺絲
interface Screw {
public void screwInfourmation();
}
//具體產品類: 8毫米螺絲
class EightMillimeterScrew implements Screw {
@Override
public void screwInfourmation() {
System.out.println("我是一個8毫米的螺絲啊。。。。");
}
}
//具體產品類: 7毫米螺絲
class SevenMillimeterScrew implements Screw {
@Override
public void screwInfourmation() {
System.out.println("我是一個7毫米的螺絲啊。。。。");
}
}
//具體產品類: 6毫米螺絲
class SixMillimeterScrew implements Screw {
@Override
public void screwInfourmation() {
System.out.println("我是一個6毫米的螺絲啊。。。。");
}
}
//螺絲工廠基類
interface ScrewFactory{
public Screw getScrew();
}
//8毫米螺絲工廠
class EightMillimeterScrewFactory implements ScrewFactory{
@Override
public Screw getScrew() {
return new EightMillimeterScrew();
}
}
//7毫米螺絲工廠
class SevenMillimeterScrewFactory implements ScrewFactory{
@Override
public Screw getScrew() {
return new SevenMillimeterScrew();
}
}
//6毫米螺絲工廠
class SixMillimeterScrewFactory implements ScrewFactory{
@Override
public Screw getScrew() {
return new SixMillimeterScrew();
}
}
二、
總結工廠以及原型設計模式,談談你們開發過程中使用使用各種框架,
見識各種源碼,在哪些地方體現了工廠模式,原型模式。
答:
工廠模式:
工廠模式實際應用中可分爲簡單工廠,工廠方法,抽象工廠三類
簡單工廠:
優點:
* 1:將具體產品的類型 從客戶端端代碼中解耦出來
* 2:服務端代碼修改了具體的產品類名 客戶端不知道,這便符合我們的 面向接口編程 的思想
* 這裏的接口不單包括 interface 只要是下層給上層暴露出來的方法、類 都可認爲是面向接口編程裏的接口形式
缺點:
* 1:type 與具體產品映射關係
* 2:如果 具體產品非常大,簡單工廠的代碼會變得非常臃腫
* 3.擴展具體產品,勢必會修改簡單工廠的代碼,違反了 開閉原則
* 4.始終丟失原始類數據
工廠方法:
優點:
* 1.具有簡單工廠的優點 符合開閉原則
* 2.擴展了新產品,不需要修改作者原來的代碼,新加一個工廠而已
缺點:
* 1.高耦合了,只知道具體工廠類名 才能修改相關具體產品
* 2.每增加一個產品等級 就要增加一個生產產品的工廠以及具體的產品類 和產品生產工廠
這樣會 造成類的爆炸式增長增加了系統複雜度 增加了開銷
* 3.一個具體工廠只能創建一個具體產品
* 4.設計太過複雜
*
* 規約:約定大於配置
* 工廠的名字 視爲接口。作爲作者,有責任和義務保證工廠的名字是趨向穩定的
抽象工廠:
優點:具備簡單工廠和工廠方法的優點
* 1.抽象工廠減少了工廠類,無論有多少的產品等級,工廠就一套
* 疑問: 爲啥具體產品要這樣搭配?
* 抽象工廠中,可以生產多個產品,這些產品必須要有邏輯關係
* 產品簇 ,產品等級
缺點:
* 1.當產品等級發生變化,需要引起所有之前的工廠代碼的修改違反了 開閉原則
結論:
* 產品等級比較固定,考慮抽象工廠
* 產品等級經常變化 不建議抽象工廠
* 產品等級少 建議工廠方法
spring bean的創建就是一個典型的工廠模式,我們無需創建Bean,Spring 的BeanFactory幫我們做到了,
我們只要在需要的地方通過依賴注入來獲取需要的實例。
原型模式:
1.類初始化需要消化非常多的資源,這個資源包括數據、硬件資源等,通過原型拷貝避免這些消耗。
2.通過new一個對象需要非常繁瑣的數據準備或訪問權限,可以使用原型模式。
3.一個對象需要提供給其他對象訪問,而且各個調用者可能需要修改其值,可以考慮使用原型模式拷貝多個對象供調用者使 用, 即保護性拷貝