为了账号安全,请及时绑定邮箱和手机立即绑定

完全透析设计模式(1)- 工厂方法

工厂方法模式(Factory Method)

工厂方法设计模式属于创建型设计模式(有的资料称构建型设计模式)。在工厂方法模式中,父类决定实例的生成方式,这种方式表现出来就是一个抽象类,所以并不决定生成的具体的类,具体的实现就交给继承的子类去实现。这里抽象的父类可以理解为“工厂”,而具体的实现子类则可以理解为“产品”。

工厂方法的角色

下图工厂方法模式UML类图:
Alt

- Product(抽象产品)

Product被定义为一个抽象类,包含了抽象产品的所有接口,它也是直接被客户端所使用的。

- Factory(抽象工厂)

Factory和Product一样都会被定义为抽象类,Factory负责定义生成Product的方法createProduct(),但具体实现则交给子类,也就是具体工厂。通过方法去创建Product,而不是用new的方式,可以让父类和具体实现达到松耦合的效果。

- ConcreateProduct(具体产品)

ConcreateProduct是具体的产品,它需要继承抽象产品去实现所有的产品方法。

- ConcreateFactory(具体工厂)

ConcreateFactory是具体的工厂,它需要继承抽象工厂去负责生成具体的产品。

实践工厂方法

假设你需要购买一辆车,你可以到4S店去取车,不需要知道工厂是怎么实现的。这里车是一个抽象的产品,具体的产品有各种各样的车。他们实现的工序是复杂的,同时又是相似的,都需要设计、购买材料、加工生成,而具体怎么设计、材料是什么样的、加工细节都会因为具体的车而不一样。

定义一部车,包含了外观的方法display()和运行表现方法run()。

public abstract class Car {

    public abstract void display();

    public abstract void run();

}

定义生成车的工厂,通过createCar()方法去创建Car对象,创建的过程是相对复杂的,需要调用design()、buyMaterial()、working()三个方法才能完成。

public abstract class CarFactory {

    public final Car createCar(){
        Car car = design();//设计
        buyMaterial(car);//购买材料
        working(car);//加工生产
        return car;
    }

    protected abstract Car design();

    protected abstract void buyMaterial(Car car);

    protected abstract void working(Car car);

}

一辆具体的车特斯拉,继承Car这个抽象类,实现抽象方法。

public class TeslaCar extends Car {

    @Override
    public void display() {
        System.out.println("科幻的黑色外观");
    }

    @Override
    public void run() {
        System.out.println("跑起来很安静");
    }

}

特斯拉环保电动车具体的生产工厂TeslaCarFactory,继承了CarFactory 抽象类,实现了design()、buyMaterial()、working()三个方法。

public class TeslaCarFactory extends CarFactory {

    @Override
    public Car design() {
        System.out.println("设计特斯拉汽车");
        TeslaCar teslaCar = new TeslaCar();
        return teslaCar;
    }

    @Override
    public void buyMaterial(Car car) {
        System.out.println("购买特斯拉汽车材料");
    }

    @Override
    public void working(Car car) {
        System.out.println("加工生产特斯拉汽车");
    }

}

一辆具体的车法拉利,继承Car这个抽象类,实现抽象方法。

public class FerrariCar extends Car {

    @Override
    public void display() {
        System.out.println("炫丽的红色外观");
    }

    @Override
    public void run() {
        System.out.println("劲爆的轰鸣声");
    }

}

法拉利豪华跑车具体的生产工厂FerrariCarFactory,继承了CarFactory 抽象类,实现了design()、buyMaterial()、working()三个方法。

public class FerrariCarFactory extends CarFactory {

    @Override
    public Car design() {
        System.out.println("设计法拉利汽车");
        FerrariCar ferrariCar = new FerrariCar();
        return ferrariCar;
    }

    @Override
    public void buyMaterial(Car car) {
        System.out.println("购买法拉利汽车材料");
    }

    @Override
    public void working(Car car) {
        System.out.println("加工生产法拉利汽车");
    }

}

有位哥们需要一辆法拉利泡妞一辆特斯拉上下班

public class Main {

    public static void main(String[] args) {
        //生产一部法拉利
        CarFactory carFactory = new FerrariCarFactory();
        Car car = carFactory.createCar();
        car.display();
        car.run();
        System.out.println("-----------------------------");
        //生产一部特斯拉
        carFactory = new TeslaCarFactory();
        car = carFactory.createCar();
        car.display();
        car.run();

    }
}

运行Main程序结果

设计法拉利汽车
购买法拉利汽车材料
加工生产法拉利汽车
炫丽的红色外观
劲爆的轰鸣声
-----------------------------
设计特斯拉汽车
购买特斯拉汽车材料
加工生产特斯拉汽车
科幻的黑色外观
跑起来很安静

使用场景

工厂模式将具体的实现封装了起来,对于调用者来说,只需要知道具体的实现工厂类即可,至于是怎么实现的则不需要关心。提高了系统的扩展性,新增一个新的产品,只需要增加一个新的工厂类即可,对于调用者只需要要选择不同的工厂类,其他地方代码不需要改变。但是随着产品的增加,具体的产品类和具体的工厂类就会不断增加,这也在一定程度上增加了系统的复杂性,难道不是直接用new去创建更方便吗?。这也就是我们使用设计模式需要注意的地方,不要为了设计模式而故意去将简单的事情搞复杂了。工厂方法设计模式应该被使用在创建对象比较复杂的时候,当一个简单的new不太行的时候就该考虑使用工厂模式,例如上面的造车操作显然是一个相对复杂的过程,这时候使用工厂模式就会使代码结构更加优雅简洁。总而言之,可以只需通过new即可完成创建的对象不需要使用工厂模式,否则反而会增加系统的复杂度,代码变臃肿。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消