简单工厂提供一个创建对象实例的功能,无须关心其具体实现。被创建的实例可以是接口、抽象类,也可以是具体的类
简单工厂的结构如下:
从上述结构可以看出,把对API的实例向客户端隐藏了,客户端在调用的时候无需关注具体实现类是哪个,只需要调用工厂创建出一个实例,然后发起调用即可。上述结构整理下如下图
在Java里面,通常情况下是用来创造接口的,但是也可以创造抽象类或普通的类。下图是简单工厂的调用顺序
简单工厂的本质
简单工厂的本质在于选择,而非实现。
所以实现简单工厂的难点就在于如何选择,我们可以采用参数传递、配置文件等等方式来尝试实现。
何时选用简单工厂
- 如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选择简单工厂。
- 如果想要把对外创建对象的职责集中管理和控制,可以选择简单工厂。
代码示例:
新增对象类
package com.mk.designDemo.designs.factory.model;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Car {
/**
* 品牌
*/
private String brand;
/**
* 名称
*/
private String name;
/**
* 生产厂家
*/
private String manufacturer;
/**
* 产地
*/
private String origin;
}
package com.mk.designDemo.designs.factory.model;
public class BMWCar extends Car {
public BMWCar(String name) {
super("BMW", name, "德国BMW", "德国代工厂");
}
}
package com.mk.designDemo.designs.factory.model;
public class BENZCar extends Car {
public BENZCar(String name) {
super("BENZ", name, "德国Benz", "德国代工厂");
}
}
新增API和实现类
package com.mk.designDemo.designs.factory;
import com.mk.designDemo.designs.factory.model.Car;
public interface CarAPI {
Car getCar(String carName);
}
package com.mk.designDemo.designs.factory.impl;
import com.mk.designDemo.designs.factory.CarAPI;
import com.mk.designDemo.designs.factory.model.BMWCar;
import com.mk.designDemo.designs.factory.model.Car;
public class BMWCarAPI implements CarAPI {
@Override
public Car getCar(String name) {
return new BMWCar(name);
}
}
package com.mk.designDemo.designs.factory.impl;
import com.mk.designDemo.designs.factory.Brand;
import com.mk.designDemo.designs.factory.CarAPI;
import com.mk.designDemo.designs.factory.model.BENZCar;
import com.mk.designDemo.designs.factory.model.Car;
@Brand("BENZ")
public class BenzCarAPI implements CarAPI {
@Override
public Car getCar(String name) {
return new BENZCar(name);
}
}
新增测试类
package com.mk.designDemo.factory;
import com.mk.designDemo.designs.factory.CarAPI;
import com.mk.designDemo.designs.factory.MyCarFactory;
import com.mk.designDemo.designs.factory.model.Car;
import org.junit.Test;
public class CarFactoryTest {
@Test
public void getCar() throws Exception {
CarAPI carAPI = MyCarFactory.getCarApi("BMW");
Car car = carAPI.getCar("2019款新宝马3系");
System.out.println(car.toString());
}
}
测试结果:
文中内容摘自《研磨设计模式》