Java设计模式(3) —— 三种工厂模式

本文探讨了为什么需要工厂模式,以及工厂模式如何解决代码耦合度高的问题。介绍了简单工厂、工厂方法和抽象工厂三种模式,通过实例展示了它们在创建对象时的不同策略,以及如何遵循设计原则,提高代码的可扩展性和复用性。
摘要由CSDN通过智能技术生成

这两天看了大名鼎鼎的工厂模式~ headfirst的这一章挺长的,pizza的例子感觉也不是特别清楚,在网上搜了搜别人的博客又看了看,在此记录一下学习感悟吧

为什么需要工厂模式?

在Java中,创建对象的方式有多种,包括:

  • 用new关键词创建,最简单常用的就是这个了
  • 通过反射机制,classA.newInstance()
  • Clone()方法复制
  • 构造器类进行对象的创建:
    Constructor c = ClassA.getConstructor();
    ClassA a = c.newInstance();
    

这几个方法里最常见的一个就是用new关键字创建新对象,但是这样的方式违背了设计模式的原则之一——不要面向具体实现编程,而应该面对抽象、接口编程

当我们new一个对象时,new后面跟的是一个具体的类,这样就对具体的类产生了依赖,耦合度较高。看一个例子:

public class CarStore {
    public Car orderCar(String str){
        Car car = null;
        if (str == "BMW")
            car = new BMW();
        if (str == "Lexus")
            car = new Lexus();
        return car;
    }
}

上面的CarStore类提供宝马车和雷克萨斯车,当这个类增加了奔驰车时,除了需要新增一个Benz类,还需要对CarStore类的代码对如下修改:

public class CarStore {
    public Car orderCar(String str){
        Car car = null;
        if (str == "BMW")
            car = new BMW();
        if (str == "Lexus")
            car = new Lexus();
        if (str == "Benz")
        	car = new Benz();
        return car;
    }
}

这样的代码违背了三个原则:

  • 单一职责原则,一个类既负责创建类,又负责使用类
  • 开闭原则(对修改关闭,对扩展开放):对于新增的功能,需要修改旧代码,不利于维护
  • 高复用原则:如果一个对象的创建比较复杂,需要多行代码,每次需要用的时候都从头到尾创建一次,重复代码多。

而工厂模式,解决的正是这样的问题。下面依次来看三种工厂模式:

1.简单工厂模式(静态工厂)

简单工厂模式,顾名思义比较简单,针对上述new关键词创建对象的弊端,简单工厂模式负责把类的创建单独封装起来,放在一个工厂类中,对于刚才的代码,简单工厂模式会这么改:

public class CarStore {
    public Car orderCar(String str){
        Car car = SimpleCarFactory.createCar(str);
        return car;
    }
}

public class SimpleCarFactory {
    public SimpleCarFactory(){ }

    public static Car createCar(String str){
        Car car = null;
        if (str == "BMW")
            car = new BMW();
        if (str == "Lexus")
            car = new Lexus();
        return car;
    }
}

可以看到,车的创建工作已经被封装起来,CarStore只需要调用工厂类的createCar方法即可,不需要知道创建的细节。这样就解决了代码重复、多重职责的问题,但是一下问题还是没有得到解决:

  • 依然违背开闭原则:如果要增加奔驰车,还是得修改SimpleCarFactory类的createCar方法的代码。
  • SimpleCarFactory是一个具体类,仍然是在面向具体类编程。

2.工厂方法模式

为了解决上述简单工厂模式的缺点,出现了工厂方法模式:定义一个工厂抽象类,声明必要的接口,让具体的子类进行对象的创建工作。代码如下:

public class CarStore {
    CarFactory carFactory;

    public CarStore(CarFactory carFactory){
        this.carFactory = carFactory;
    }

    public Car orderCar(String str){
        Car car = carFactory.createCar();
        return car;
    }
}


public interface CarFactory {
    Car createCar();
}


public class LexusCarFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Lexus();
    }
}


public class BMWCarFactory implements CarFactory{
    @Override
    public Car createCar(){
        return new BMW();
    }

}

这样一来,当需要增加奔驰车的时候,增加一个Benz类和一个BenzCarFactory类就可以了,不需要修改原有代码。而且CarStore依赖的是CarFactory接口而不是具体类。

抽象工厂模式

对于简单工厂模式而言,当车的种类越来越多后,单一工厂类的职责过重,会变得很臃肿。

而对于工厂方法模式,如果每多一种车就要新建一个工厂类+一个车类型,类的数量会快速扩张、变得越来越多不利于维护和管理。

因此,对于相互关联、依赖的类型,他们可以形成一个产品族,放到同一个工厂类中进行创建。比如车的配件工厂类,每种车的配件种类都差不多,就可以形成一个产品族。

在抽象工厂模式中,首先定义一个抽象工厂类或接口,声明需要创建的产品有哪些,由具体类对这些产品进行实现,如下:

public interface CarAccessoryFactory {
    Wheel createWheel();
    Window createWindow();
    CarDoor createCarDoor();
}

public class BMWCarAccessoryFactory{
	BMWWheel createWheel(){
		return new BMWWheel();
	}
	BMWWheel createWindow(){
		return new BMWWhindow();
	}
	BMWWheel createCarDoor(){
		return new BMWCarDoor();
	}
}

显而易见,抽象工厂模式的一个弊端就是,如果产品族发生了改变,比如车配件增加了一个底盘,这时候就需要对CarAccessoryFactory和所有实现这个接口的具体类进行更改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值