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;
/**
* 简单的工厂模式
* 我的博客地址:
*
* @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 com.coline.design.factory.abstractway.intf.PhoneFactory;
import org.junit.Test;
/**
* @author Coline
* @ClassName CreatePhoneTest
* @Date 2020/2/2 0:39
* @Description 抽象工厂模式测试类
* 我的博客地址:
*/
public class CreatePhoneTest {
@Test
public void testCreatPhone() {
System.out.println("----------------------------");
System.out.println("Create XiaoMi");
PhoneFactory xiaomi = new XiaoMi();
xiaomi.getCpu();
xiaomi.getScreen();
System.out.println("----------------------------");
System.out.println("Create Huawei");
PhoneFactory huawei = new HuaWei();
huawei.getCpu();
huawei.getScreen();
}
}
测试结果如下: