设计模式 之 工厂模式

简单工厂

简单工厂不能算是一个设计模式,简单工厂只能算一个编程技巧

就是使用一个简单的 switch case 来创建对应对象

public class SimpleFac {
    public static Car simpleCarFactory(String type) {
        switch (type) {
            case "Audi":
                return new Audi();
            case "Bmw":
                return new Bmw();
            case "Benz":
                return new Benz();
            default:
                return null;
        }
    }
}

其使用方式,和不用注解的Spring差不多:

Spring出现之前,都是用这种方式处理的

public class CarStore {
    public Car orderCar(String type) {
        Car car=null;
        car= SimpleFac.simpleCarFactory(type);

        car.installSeat();
        car.installWheel();
        car.paint();

        return car;
    }
}

主函数和测试结果如下:

public class Main {
    public static void main(String[] args) {
        CarStore carStore = new CarStore();
        Car audi = carStore.orderCar("Audi");
    }
}

image-20210401084007169

其类图如下:

image-20210401085407516


工厂方法

工厂不再是一个具体类,而是将其作为一个抽象方法,交给子类来实现:

public abstract class CarStore {
    public Car orderCar(String type) {
        Car car=null;

        /**
         * 使用工厂方法后,就没有具体的工厂实现了
         */
        // car= SimpleCarFactory.createCar(type);

        /**
         * 只关心使用,不关心实现
         * 这就是解耦
         */
        car=createCar(type);

        car.installSeat();
        car.installWheel();
        car.paint();

        return car;
    }

    /**
     * 抽象的创建方法
     * 交给子类去实现
     * @param type
     * @return
     */
    abstract Car createCar(String type);
}

我们来看看其子类的实现:

BeijingCarStore:

public class BeijingCarStore extends CarStore{

    @Override
    Car createCar(String type) {
        switch (type) {
            case "Audi":
                return new BeijingAudi();
            case "Bmw":
                return new BeijingBmw();
            case "Benz":
                return new BeijingBenz();
            default:
                return null;
        }
    }

}

ChanganCarStore:

public class ChanganCarStore extends CarStore{

    @Override
    Car createCar(String type) {
        switch (type) {
            case "Audi":
                return new ChanganAudi();
            case "Bmw":
                return new ChanganBmw();
            case "Benz":
                return new ChanganBenz();
            default:
                return null;
        }
    }
}

测试:

public class Main {
    public static void main(String[] args) {
        BeijingCarStore beijingCarStore = new BeijingCarStore();
        ChanganCarStore changanCarStore = new ChanganCarStore();

        Car beijingAudi = beijingCarStore.orderCar("Audi");
        Car changanAudi = changanCarStore.orderCar("Audi");
    }
}

image-20210401092045646

工厂方法的类图如下:

image-20210331111925400

工厂方法简而言之,就是父类表示一个创建对象的逻辑,但这个创建对象的具体实现,是让子类去实现的,从而可以实现子类的自定义实现。

如果对上面的实例,不太清楚,我们可以来模仿一个Spring的调用方式:

public class SpringLikeUse {
    //指明实现的位置
    @Source(name ="BeijingCarStore")
    CarStore store;

    public void driveCar() {
        Car audi = store.orderCar("Audi");
        System.out.println("我正在驾驶"+audi);
    }
}

有没有一点感觉

其一,是解耦。如果我们没有CarStore这个父类,只有不同的工厂实现,那当我们想修改工厂实现的时候,就要更改很多代码。

image-20210401101637081

父类调用create()的过程,其实也是一个解耦的过程

image-20210401102123590

抽象工厂

抽象工厂,其实就是定义一个工厂接口,然后,让所有与之相关的工厂,都实现这个接口。

与我看类,抽象工厂,就是一般的接口使用

通过这种实现接口的方式,用抽象工厂,可以表示构造一个族

我建立一个抽象工厂,用来定义车零部件生产的接口:

public interface CarPartFactory {
    Paint createPaint();
    Seat createSeat();
    Wheel createWheel();
}

这里有一家超高级汽车部件制造商,需要和市场需求匹配(继承我的抽象工厂接口):

public class SuperHighClassCarPartFactory implements CarPartFactory{
    @Override
    public Paint createPaint() {
        return new FuckingExpensivePaint();
    }

    @Override
    public Seat createSeat() {
        return new FuckingExpensiveSeat();
    }

    @Override
    public Wheel createWheel() {
        return new FuckingExpensiveWheel();
    }
}

北京奥迪的部件想要让这家超高级汽车部件厂商来做的时候,就需要委托他:

public class BeijingAudi extends Audi{

    CarPartFactory partFactory;

    public BeijingAudi() {
        this.name="北京 "+this.name;
        this.price=this.price*0.8;
    }

    /**
     * 从外部,实例化 抽象工厂CarPartFactory
     * @param partFactory
     */
    public BeijingAudi(CarPartFactory partFactory) {
        this.partFactory = partFactory;
        this.name="北京 "+this.name;
        this.price=this.price*0.8;
    }

    public void prepare() {
        this.seat=partFactory.createSeat();
        this.paint=partFactory.createPaint();
        this.wheel=partFactory.createWheel();
    }

    @Override
    public void detail() {
        prepare();
        super.detail();
        System.out.println("这是北京奥迪,打了8折");
        System.out.println(this.toString());
    }
}

image-20210401173932123

抽象工厂的类图如下:

image-20210331115703927

工厂方法和抽象工厂的区别

工厂方法

image-20210401174100215

抽象工厂

image-20210401174112020

再说得简单一点:

工厂方法,就是父类调用抽象的创建方法,而子类去实现这个抽象的创建方法,从而在调用的时候,可以保证创建成功。

抽象工厂,就是定义一个接口,让相关类的具体工厂,都去实现这个接口,从而实现方法的统一

再说的简单一点:

工厂方法抽象的父类使用抽象方法逻辑,子类实现抽象方法

抽象工厂实现接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FARO_Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值