设计模式_工厂模式

模式:创建型模式

✨ 普通的工厂模式
优点:编写简单,清晰
缺点:当工厂需要生产多一个车型,那就需要更改“工厂类”的代码,这样对开闭原则不好。

/**
 * 车的接口
 * */
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();
	}
}

同理,若我们再向增加多一个车辆的牌子生产,我们只需要遵循以下步骤

  1. 增加相关的汽车类,实现 C调用其product方法即可。
    ar 接口
  2. 增加相关汽车类的工厂,实现 Factory
  3. 通过实例化新增的汽车类的工厂类
    这样做的好处是,当我们新增的类的时候,不需要更改源码,只需要增加相关的类。

但是这个模式还是不够完美。比如说,我想要一个 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();
    }
}

其实细心一点的同学就会发现,其实工厂抽象工厂之间的不同之处在于,工厂的抽象维度在于产品,一个工厂只能生产一个产品;而抽象工厂的抽象维度在于工厂,这个工厂是可以生产多系列的产品。

posted on 2019-04-08 16:01  野区杰西  阅读(114)  评论(0编辑  收藏  举报

导航