工厂模式
作用:创建者和调用者分离解耦
核心本质:实例化对象不使用new,用工厂方法代替
分类:
简单工厂模式
假设我们的消费者需要购买五菱和特斯拉2个品牌的汽车,首先我们会创建一个Car的汽车接口,这个接口中约定了name()方法会得到品牌的名字,然后我们创建WuLing(五菱)和Tesla(特斯拉)两个子类去实现Car接口。最后我们创建一个工厂类去生产这两个品牌的汽车。消费者只要通过这个工厂类就可以得到对应品牌的实例
简单工厂模式图例:
Car接口
public interface Car {
void name();
}
汽车类:
第一种汽车类:WuLing
public class WuLing implements Car{
@Override
public void name() {
System.out.println("五菱");
}
}
第二种汽车类:Tesla
public class Tesla implements Car{
@Override
public void name() {
System.out.println("特斯拉");
}
}
工厂类:
这时候,创建一个工厂类,这个工厂即可以生产五菱,也可以生产特斯拉
public class CarFactory {
public static Car getCar(String car){
if (car.equals("五菱")){
return new WuLing();
}
else if(car.equals("特斯拉")){
return new Tesla();
}else {
return null;
}
}
}
消费者类:
public static void main(String[] args) {
//Car car1 = new WuLing();
//Car car2 = new Tesla();
Car car1 = CarFactory.getCar("五菱");
Car car2 = CarFactory.getCar("特斯拉");
car1.name();
car2.name();
}
}
运行结果:
简单工厂方法实现如上,其中会存在一定的问题,假设我现在要一种其他品牌的车
例如新增大众品牌:
public class Volkswagen implements Car{
@Override
public void name() {
System.out.println("大众");
}
}
我们的方式可以还是和之前一样,首先增加一个大众汽车类实现Car接口,然后修改工厂类中的getcar()方法,毫无疑问是可用实现的,但是如果后续还会不停的增加其他品牌的汽车,每一次都要修改工厂类中的getcar()方法。这是违反了 开闭原则 的,我们设计程序时总是希望出现扩展时尽量减少对前期代码的修改。
开闭原则:软件中的 对象 ( 类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的。
工厂方法模式
工厂方法模式解决了上面简单工厂的问题
实现思路是:简单工厂方法的一个汽车工厂能生产所有品牌的汽车,现在我们将汽车工厂抽象为一个总工厂接口,然后创建每个品牌对应的工厂实现这个总工厂接口,并被它约束,然后我们需要拓展其他的汽车品牌,只需要增加相应品牌的汽车类和汽车工厂类,就可以实现不修改之前的代码,进行扩展了。
工厂方法模式图例:
1、将CarFactory变为总工厂接口
//工厂方法模式
public interface CarFactory {
Car getcar();
}
2、增加车企对应的工厂类
2.1五菱:
public class WuLingFactory implements CarFactory{
@Override
public Car getcar() {
return new WuLing();
}
}
2.2特斯拉:
public class TeslaFactory implements CarFactory{
@Override
public Car getcar() {
return new Tesla();
}
}
2.3大众:
public class VolkswagenFactory implements CarFactory{
@Override
public Car getcar() {
return new Volkswagen();
}
}
3、消费者类:
不再是通过CarFactory来获得对应的汽车,而是通过对应的汽车工厂获得汽车
public class Consumer {
public static void main(String[] args) {
Car car1 = new WuLingFactory().getcar();
Car car2 = new TeslaFactory().getcar();
Car car3 = new VolkswagenFactory().getcar();
car1.name();
car2.name();
car3.name();
}
}
运行结果:
总结:
以上就是工厂模式的2种方式,我们对2种方式进行对比,工厂方法模式虽然不会违反开闭原则,但在结构和编码复杂度上都会提升,一定程度上会有代码的冗余。在实际生产中简单工厂模式反而使用的更多,所以选择什么样的工厂模式是需要根据设计的需求来选择:
根据设计原则:使用工厂方法模式。
更具实际业务:使用简单工厂模式。
那么什么是抽象工厂模式呢?,它解决的是另一个问题