什么是工厂模式?
Java的工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。这种类型的设计模式属于创建型模式,它提供了了一种创建对象的最佳方式。在Java中,工厂模式常常用于创建实例对象,例如通过一个工厂方法来创建对象,而不是直接使用new关键字。这样可以使代码更加灵活,易于扩展和修改。
为什么要有工厂模式?
很多人都会纠结于“既然都有了构造函数,何必再折腾那么多事情呢”。为了解答这个问题,先解释下构造函数是干什么用的。先用最早出现的C,创建资源差不多要这么干:some_struct * p =
(some_struct*)malloc(sizeof(some_struct)); init_some_struct§;
do_something§;
即先分配内存,再做类型转换,再初始化,然后使用。而在OOP的时代,创建一个对象是很频繁的事情。同时,一个没初始化的数据结构是无法使用的。因此,构造函数被发明出来,将分配内存+初始化合并到了一起。如C++的语法是:
SomeClz *p = new SomeClz(); do_something§; // or
p.do_something_else();
java也沿用了这个设计。但是,整个构造函数完成的工作从更高层的代码设计角度还是太过于初级。因此复杂的创建逻辑还是需要写代码来控制。所以还是需要:
SomeClz * createSomeClz(…) { // 做一些逻辑 SomeClz *p = new SomeClz();
// 或者复用已经有的对象 // 再做一些额外的初始化 return p; }
这就是Factory的雏形。
引用来自知乎,作者:大宽宽
工厂模式的三种形态
简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。《设计模式》一书中将工厂模式分为两类:工厂方法模式与抽象工厂模式。将简单工厂模式看为工厂方法模式的一种特例,两者归为一类。 我们先从以下案例对工厂模式做个初步的了解:
(1)在没有工厂的时代,如果客户需要一款宝马车,那么就需要客户去创建一款宝马车,然后拿来用。
(2)简单工厂模式:后来出现了工厂,用户不再需要去创建宝马车,由工厂进行创建,想要什么车,直接通过工厂创建就可以了。比如想要320i系列车,工厂就创建这个系列的车。
(3)工厂方法模式:为了满足客户,宝马车系列越来越多,如320i、523i等等系列,一个工厂无法创建所有的宝马系列,于是又单独分出来多个具体的工厂,每个具体工厂创建一种系列,即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象,你需要指定某个具体的工厂才能生产车出来。
(4)抽象工厂模式:随着客户要求越来越高,宝马车必须配置空调,于是这个工厂开始生产宝马车和需要的空调。最终是客户只要对宝马的销售员说:我要523i空调车,销售员就直接给他523i空调车了。而不用自己去创建523i空调车宝马车。
引用来自CSDN博主「张维鹏」的原创文章
具体实现
简单工厂模式
// 引入一个抽象类,声明其构造方法。
public abstract class SmartPhone {
public SmartPhone(){
}
}
// 引入HUAWEI类,集成手机类,并实现抽象方法
public class HUAWEI extends SmartPhone {
public HUAWEI(){
System.out.println("HUAWEI 666");
}
}
// 引入IPHONE类,集成手机类,并实现抽象方法
public class IPHONE extends SmartPhone {
public IPHONE(){
System.out.println("IPHONE 666");
}
}
这样,我们就有了两个类,都分别继承了手机类
// 创建工厂,PhoneFactory ,入参为1,创建实体华为。入参为2,创建实体苹果
public class PhoneFactory {
public SmartPhone createPhone(int param){
if(param == 1){
return new HUAWEI();
}
if(param == 2){
return new IPHONE();
}
else {
return null;
}
}
}
运用工厂进行实例化:
public class AdminTest {
public static void main(String[] args) {
PhoneFactory phoneFactory = new PhoneFactory();
SmartPhone phone = phoneFactory.createPhone(1);
}
}
输出:
工厂方法模式
简单工厂模式的缺点就是,如果有很多个类都要继承手机类,那么工厂类的判断方法就会特别冗余。
所以我们有了工厂方法模式。
public interface Factory {
SmartPhone createSmartPhone();
}
public class HuaweiFactory implements Factory {
@Override
public SmartPhone createSmartPhone() {
return new HUAWEI();
}
}
public class IphoneFactory implements Factory {
@Override
public SmartPhone createSmartPhone() {
return new IPHONE();
}
}
运用:
public class AdminTest {
public static void main(String[] args) {
IphoneFactory iphoneFactory = new IphoneFactory();
SmartPhone smartPhone = iphoneFactory.createSmartPhone();
}
}
抽象工厂模式
我要创建很多,比如说生产电脑的同时,生产了显卡和cpu。
这时,我们引入抽象工厂模式的概念。
简单的讲,就是直接抽象工厂出来,而不是工厂生产的具体实例。
先创建三个接口,分别是电脑,显卡和cpu
public interface Computer {
void makeGPU();
void makeCPU();
}
public interface CPU {
void makeCPU();
}
public interface GPU {
void makeGPU();
}
显卡和cpu的实例
public class AMDCPU implements CPU {
@Override
public void makeCPU() {
System.out.println("AMD YYDS!");
}
}
public class IntelCPU implements CPU {
@Override
public void makeCPU() {
System.out.println("INTEL 666!");
}
}
public class AMDGPU implements GPU {
@Override
public void makeGPU() {
System.out.println("AMD的显卡世界第一!");
}
}
public class IntelGPU implements GPU {
@Override
public void makeGPU() {
System.out.println("有钱人都买英特尔的显卡!");
}
}
创建工厂类,分别实现amd或者Intel
public class AMDComputer implements Computer {
@Override
public void makeGPU() {
AMDGPU amdgpu = new AMDGPU();
amdgpu.makeGPU();
}
@Override
public void makeCPU() {
AMDCPU amdcpu = new AMDCPU();
amdcpu.makeCPU();
}
}
public class INTELComputer implements Computer {
@Override
public void makeGPU() {
IntelGPU intelGPU = new IntelGPU();
intelGPU.makeGPU();
}
@Override
public void makeCPU() {
IntelCPU intelGPU = new IntelCPU();
intelGPU.makeCPU();
}
}
通过抽象工厂创建电脑实例
public class AdminTest {
public static void main(String[] args) {
AMDComputer amdComputer = new AMDComputer();
amdComputer.makeCPU();
amdComputer.makeGPU();
}
}