设计模式_工厂模式
模式:创建型模式
✨ 普通的工厂模式
优点:编写简单,清晰
缺点:当工厂需要生产多一个车型,那就需要更改“工厂类”的代码,这样对开闭原则不好。
/**
* 车的接口
* */
public interface Car {
public void drive();
}
/**
* 奔驰
* */
class Benz implements Car{
@Override
public void drive() {
System.out.println("Benz");
}
}
/**
* 宝马
* */
class BMW implements Car{
@Override
public void drive() {
System.out.println("BMW");
}
}
class CarFactory {
public Car productCar(String car) {
if ("Benz".equals(car)) {
return new Benz();
} else if("BMW".equals(car)) {
return new BMW();
}
return null;
}
}
✨ 工厂方法模式
优点:解决了“普通工厂方法”中破坏的开闭原则。为了阻止“增加一个牌子就需要改一下工厂源码”,我们决定换个思路来解决这个问题-“增加类”。当需要增加一个牌子的时候,我们就相应增加一个工厂类。利用 Java 多态特性来解决这个问题。
我们继续使用上面的代码作为这个栏目的示例。
/**
* 比亚迪
* */
class BYD implements Car{
@Override
public void drive() {
System.out.println("BYD");
}
}
我们将相关的车辆抽象成一个工厂
/**
* 工厂接口
* */
interface Factory {
void product() ;
}
然后生成一个"比亚迪"的工厂
/**
* 比亚迪 - 工厂
* */
class BYDFactory implements Factory {
@Override
public BYD product() {
return new BYD();
}
}
然后当我们想生产一个比亚迪的车辆,我们只需要这么写
class Test {
public static void main(String[] args) {
Factory factory = new BYDFactory();
factory.product();
}
}
同理,若我们再向增加多一个车辆的牌子生产,我们只需要遵循以下步骤
- 增加相关的汽车类,实现 C调用其
product
方法即可。
ar 接口 - 增加相关汽车类的工厂,实现 Factory
- 通过实例化新增的汽车类的工厂类,
这样做的好处是,当我们新增的类的时候,不需要更改源码,只需要增加相关的类。
但是这个模式还是不够完美。比如说,我想要一个 beaz 牌子的轮胎,我就加一个 beaz 的相关类及工厂类;我想要一个 beaz 牌子的轮胎,我就加一个 BYD 的相关类及工厂类...
太可怕了。这样子加的类只会越来越多。
那该怎么办?
或许有人已经注意到了,其实无论是轮胎还是后视镜,只要你想要的是 beaz 这个牌子的产品,那么我们可以以牌子为维度来抽象。所以不仅仅是产品(如 beaz 轮胎)可以抽象,其实工厂也可以抽象!下面将讲解对工厂的抽象。
✨ 抽象工厂模式
既然 beaz 不仅仅生产汽车,它还生产方向盘,雨刷,轮胎等等。所以我们可以认为抽象出一个工厂接口,定义好这个
这类抽象的方法。
public interface CarFactory {
void createCar();
Screen createScreen();
AimingCircle createAimingCircle();
}
/**
* 屏幕抽象
* */
interface Screen {
}
/** 方向盘接口 */
interface AimingCircle {
}
/** 奔驰屏幕实现 */
class BenzScreen implements Screen {
}
/** 奔驰方向盘实现 */
class BenzAimingCircle implements AimingCircle {
}
/** 比亚迪屏幕实现 */
class BYDScreen implements Screen {
}
/** 比亚迪方向盘实现 */
class BYDAimingCircle implements AimingCircle {
}
/** 奔驰 一系列工厂 */
class BenzFactory implements CarFactory {
@Override
public void createCar() {
System.out.println("创建一辆奔驰车");
}
@Override
public Screen createScreen() {
return new BenzScreen();
}
@Override
public AimingCircle createAimingCircle() {
return new BenzAimingCircle();
}
}
/** BYD 一系列工厂 */
class BYDFactory implements CarFactory {
@Override
public void createCar() {
System.out.println("创建一辆奔驰车");
}
@Override
public Screen createScreen() {
return new BYDScreen();
}
@Override
public AimingCircle createAimingCircle() {
return new BYDAimingCircle();
}
}
其实细心一点的同学就会发现,其实工厂和抽象工厂之间的不同之处在于,工厂的抽象维度在于产品,一个工厂只能生产一个产品;而抽象工厂的抽象维度在于工厂,这个工厂是可以生产多系列的产品。