1. 小聲嗶嗶
工廠設計模式算是經常在項目中使用的設計模式,屬於創建型模式,可以理解爲創建對象的設計模式。
應用場景:根據業務情況需創建不同類型的對象,且對象又存在相似的業務邏輯,此時需要將創建對象的責任交由工廠類,工廠類會基於輸入創建對象。(該場景是根據自己的理解)
在查閱資料時看到有人講工廠設計模式分爲三類,簡單工廠,工廠方法,抽象工廠,結合開發經驗而言,簡單工廠和抽象工廠是我使用較多的模式,所以本文僅着墨於此。
文中的代碼庫:https://gitee.com/Coline/JobWanted
模塊位置:design模塊的com.coline.design.factory包中
2. 簡單工廠模式
簡單工廠模式就是我們平時使用最多的模式,假設我們項目需要小米手機和華爲手機兩種手機,手機需要選擇CPU和屏幕型號,首先我們有一個手機類型的接口PhoneType (其實這裏涉及到了模板涉及模式,也是JDK中使用較多的設計模式)
package com.coline.design.factory.simplyway.intf;
/**
* @author Coline
* @Description 手機類型接口類
*/
public interface PhoneType {
/**
* CPU型號
*/
void cpu();
/**
* 屏幕型號
*/
void screen();
}
新建小米手機類和華爲手機類並實現PhoneType ,如下:
package com.coline.design.factory.simplyway.imp;
import com.coline.design.factory.simplyway.intf.PhoneType;
/**
* @author Coline
* @Description 小米產品,繼承PhoneType接口
*/
public class XiaoMi implements PhoneType {
@Override
public void cpu() {
System.out.println("XiaoMi Cpu: 650");
}
@Override
public void screen() {
System.out.println("XiaoMi Screen: 5.5");
}
}
package com.coline.design.factory.simplyway.imp;
import com.coline.design.factory.simplyway.intf.PhoneType;
/**
* @author Coline
* @Description 華爲產品,繼承PhoneType接口
*/
public class HuaWei implements PhoneType {
@Override
public void cpu() {
System.out.println("HuaWei CPU: 950");
}
@Override
public void screen() {
System.out.println("HuaWei Screen: 6.0");
}
}
如果不使用工廠設計模式,那麼我們會在項目中的各個位置到處new這兩個實現類,代碼會顯得不優雅,丟失了程序員的尊嚴。所以我們可以將新建對象的職責交由工廠類來完成,代碼如下:
package com.coline.design.factory.simplyway;
import com.coline.design.factory.simplyway.imp.HuaWei;
import com.coline.design.factory.simplyway.imp.XiaoMi;
import org.junit.Test;
/**
* 簡單的工廠模式
* 我的博客地址:https://blog.csdn.net/u011294519/article/details/104150400
*
* @author Coline
* @ClassName PhoneFactoryTest
* @Date 2020/2/1 23:45
*/
public class PhoneFactoryTest {
private final static String XIAOMI = "XIAOMI";
private final static String HUAWEI = "HUAWEI";
Object createPhone(String brand) {
if (XIAOMI.equals(brand)) {
return new XiaoMi();
} else if (HUAWEI.equals(brand)) {
return new HuaWei();
} else {
throw new IllegalArgumentException("Param error");
}
}
@Test
public void testPhoneFactory() {
XiaoMi xiaomi = (XiaoMi) createPhone(XIAOMI);
xiaomi.cpu();
xiaomi.screen();
HuaWei huawei = (HuaWei) createPhone(HUAWEI);
huawei.cpu();
huawei.screen();
}
}
上面PhoneFactory類中的main方法僅做測試使用,僅供參考,測試結果如下:
3. 抽象工廠
抽象工廠是爲了應對更加複雜的業務情況,業務更便於擴展,主要設計思想是以業務屬性爲維度,將代碼邏輯上移至業務屬性,方便批量處理。
業務場景:假設還是小米手機和華爲手機的場景,手機廠商會根據戰略目標選擇不同的CPU和屏幕來滿足不同層級的需求,因此可以將CPU和屏幕理解爲與手機本身爲配件和整體的關係,所以首先我們有CPU的接口類,屏幕的接口類用於規範有哪些CPU和屏幕型號,代碼如下:
package com.coline.design.factory.abstractway.intf;
/**
* @author Coline
* @ClassName Cpu
* @Date 2020/2/2 0:03
* @Description Cpu工廠
*/
public interface Cpu {
/**
* CPU型號
* @return: void
**/
void model();
/**
* @ClassName Cpu850
* @Date 2020/2/2 0:31
* @Description Cpu850
*/
class Cpu850 implements Cpu {
@Override
public void model() {
System.out.println("Use Cpu850");
}
}
/**
* @ClassName Cpu950
* @Date 2020/2/2 0:32
* @Description Cpu950
*/
class Cpu950 implements Cpu {
@Override
public void model() {
System.out.println("Use Cpu950");
}
}
}
package com.coline.design.factory.abstractway.intf;
/**
* @author Coline
* @ClassName Screen
* @Date 2020/2/2 0:11
* @Description 屏幕工廠
*/
public interface Screen {
/**
* 型號
* @return: void
**/
void model();
/**
* @ClassName Screen5
* @Date 2020/2/2 0:33
* @Description Screen5
*/
class Screen5 implements Screen {
@Override
public void model() {
System.out.println("Use Screen 5");
}
}
/**
* @ClassName Screen6
* @Date 2020/2/2 0:33
* @Description Screen6
*/
class Screen6 implements Screen {
@Override
public void model() {
System.out.println("Use Screen 6");
}
}
}
同時我們需要一個手機的工廠接口類用於規範手機的組成,代碼如下:
package com.coline.design.factory.abstractway.intf;
/**
* @author Coline
* @ClassName PhoneFactory
* @Date 2020/2/2 0:27
* @Description 手機工廠
*/
public interface PhoneFactory {
/**
* 手機需要什麼CPU
* @return: void
**/
void getCpu();
/**
* 手機需要什麼屏幕
* @return: void
**/
void getScreen();
}
而後,我們根據業務需求,新建具體的手機類並實現手機工廠接口PhoneFactory
package com.coline.design.factory.abstractway.imp;
import com.coline.design.factory.abstractway.intf.Cpu;
import com.coline.design.factory.abstractway.intf.PhoneFactory;
import com.coline.design.factory.abstractway.intf.Screen;
/**
* @author Coline
* @ClassName XiaoMi
* @Date 2020/2/2 0:36
* @Description 小米手機,CPU850,屏幕5寸
*/
public class XiaoMi implements PhoneFactory {
@Override
public void getCpu() {
new Cpu.Cpu850().model();
}
@Override
public void getScreen() {
new Screen.Screen5().model();
}
}
package com.coline.design.factory.abstractway.imp;
import com.coline.design.factory.abstractway.intf.Cpu;
import com.coline.design.factory.abstractway.intf.PhoneFactory;
import com.coline.design.factory.abstractway.intf.Screen;
/**
* @author Coline
* @ClassName HuaWei
* @Date 2020/2/2 0:38
* @Description 華爲手機CPU950,屏幕6寸
*/
public class HuaWei implements PhoneFactory{
@Override
public void getCpu() {
new Cpu.Cpu950().model();
}
@Override
public void getScreen() {
new Screen.Screen6().model();
}
}
代碼邏輯就此完成,測試類如下:
package com.coline.design.factory.abstractway;
import com.coline.design.factory.abstractway.imp.HuaWei;
import com.coline.design.factory.abstractway.imp.XiaoMi;
import org.junit.Test;
/**
* @author Coline
* @ClassName CreatePhoneTest
* @Date 2020/2/2 0:39
* @Description 抽象工廠模式測試類
* 我的博客地址:https://blog.csdn.net/u011294519/article/details/104150400
*/
public class CreatePhoneTest {
@Test
public void testCreatPhone() {
System.out.println("----------------------------");
System.out.println("Create XiaoMi");
XiaoMi xiaomi = new XiaoMi();
xiaomi.getCpu();
xiaomi.getScreen();
System.out.println("----------------------------");
System.out.println("Create Huawei");
HuaWei huawei = new HuaWei();
huawei.getCpu();
huawei.getScreen();
}
}
測試結果如下: