小侃设计模式(三)-工厂模式

1.概述

设计模式中,工厂模式和抽象工厂模式都是创建型模式的代表,它提供了一种创建对象的最佳方式,是JAVA中较为常用的一种创建对象的模式。本文将分析工厂模式原理,并使用案例进行讲解。

2.工厂模式

2.1 工厂模式

工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,简单工厂模式定义了一个创建对象的类,由这个类来封装实例化对象的行为,简单工厂模式是工厂模式中最简单实用的模式。
案例:有一个抽象类Car,内部有一些抽象方法,BenzCar和BMWCar都是Car的具体实现类,CarFactory可以根据传入type来选择创建BenzCar或者BMWCar,类图如下:

在这里插入图片描述

编码如下:

public abstract class Car {

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    private String name;

    private String color;

    public void prepareCar() {
    }

    public void makeCar() {
    }

    public void testCar() {
    }

    public void haveCar() {
    }
}

public class BMWCar extends Car {

    public BMWCar() {
        this.setName("宝马");
        this.setColor("Red");
    }

    public void prepareCar() {
        System.out.println("准备" + getColor() + ":" + getName() + "车造车材料......");
    }

    public void makeCar() {
        System.out.println("准备" + getColor() + ":" + getName() + "车造车材料......");
    }

    public void testCar() {
        System.out.println("测试" + getColor() + ":" + getName() + "车性能......");
    }

    public String getName() {
        return super.getName();
    }

    public void haveCar() {
        prepareCar();
        makeCar();
        testCar();
        System.out.println("恭喜有了一辆新车" + ":" + getName());
    }
}

public class BenzCar extends Car {

    public BenzCar() {
        this.setName("奔驰");
        this.setColor("White");
    }

    public void prepareCar() {
        System.out.println("准备" + getColor() + ":" + getName() + "车造车材料......");
    }

    public void makeCar() {
        System.out.println("准备" + getColor() + ":" + getName() + "车造车材料......");
    }

    public void testCar() {
        System.out.println("测试" + getColor() + ":" + getName() + "车性能......");
    }

    public String getName() {
        return super.getName();
    }

    public void haveCar() {
        prepareCar();
        makeCar();
        testCar();
        System.out.println("恭喜有了一辆新车" + ":" + getName());
    }

}

public class CarFactory {

    public Car createCar(String type) {
        if (type.equals("benz")) {
            return new BenzCar();
        } else if (type.equals("bmw")) {
            return new BMWCar();
        } else
            return null;
    }

    public static void main(String[] args) {
        CarFactory carFactory = new CarFactory();
        Car benz = carFactory.createCar("benz");
        benz.haveCar();

        Car bmw = carFactory.createCar("bmw");
        bmw.haveCar();
    }

}

工厂模式优势:
(1)一个调用者想创建一个对象,只要知道其名称就可以了;
(2)扩展性较高,如果想增加一个产品,只需添加一个工厂类即可;
(3)屏蔽了产品的具体实现,调用者之关系创建对象的接口。
工厂模式缺点:
每次增加一个产品时,都需要增加一个具体类和对象工厂的实现,使得系统中的类个数大量增加,工厂中创建对象的代码不断增加,一定程度上增加了系统复杂度。

2.2 抽象工厂模式

定义:抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂,该超级工厂又称为其它工厂的工厂。 在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。抽象工厂模式的本质是抽象顶层接口(负责相关工厂的创建),工厂负责生产产品所需要的所有成分,当需要制定成分,调用指定工厂类生产,最后进行组合,形成完整的产品。抽象工厂的使用场景在于:系统的产品有多个的产品族, 而系统只消费其中某一族的产品。
案例:汽车工厂CarFactory负责生产汽车,汽车需要引擎和轮胎这些东西组合而成。引擎工厂Enginefactory负责生产不同的引擎,TireFactory负责生产不同的轮胎。
类图如下:

在这里插入图片描述
代码如下:

public abstract class CarFactory {

    public abstract Engine createEngine(String type);

    public abstract Tire createTire(String type);

}

public class EngineFactory extends CarFactory {
    
    public Engine createEngine(String type) {
        if (type.equals("bmw")) {
            return new BMWEngine();
        }else if (type.equals("benz")) {
            return new BenzEngine();
        }
        return null;
    }

    public Tire createTire(String type) {
        return null;
    }
}

public class TireFactory extends CarFactory{

    public Engine createEngine(String type) {
        return null;
    }

    public Tire createTire(String type){
        if (type.equals("bmw")) {
            return new BMWTire();
        }else if (type.equals("benz")) {
            return new BenzTire();
        }
        return null;
    }
}

public class BenzEngine extends Engine {

    public void turnOn(){
        System.out.println("启动引擎");
        System.out.println("Benz引擎启动");
    }

    public void turnOff(){
        System.out.println("关闭引擎");
        System.out.println("Benz引擎关闭");
    }

}

public class BMWEngine extends Engine {
    public void turnOn() {
        System.out.println("启动引擎");
        System.out.println("BMW引擎启动");
    }

    public void turnOff() {
        System.out.println("关闭引擎");
        System.out.println("BMW引擎关闭");
    }
}

public class BenzTire extends Tire {
    public void productTire() {
        System.out.println("生产轮胎");
        System.out.println("BMW 轮胎生产完成");
    }

    public void testTire() {
        System.out.println("测试轮胎");
        System.out.println("BMW 轮胎测试完成");
    }
}

public class BMWTire extends Tire {
    public void productTire() {
        System.out.println("生产轮胎");
        System.out.println("BMW 轮胎生产完成");
    }

    public void testTire() {
        System.out.println("测试轮胎");
        System.out.println("BMW 轮胎测试完成");
    }
}

public abstract class Engine {

    private String name;

    public void turnOn(){
        System.out.println("启动引擎");
    }

    public void turnOff(){
        System.out.println("关闭引擎");
    }
}

public abstract class Tire {

    private String name;

    public void productTire() {
        System.out.println("生产轮胎");
    }

    public void testTire() {
        System.out.println("测试轮胎");
    }
}

public class FactoryProducer {

    public static CarFactory getFactory(String choice) {
        if (choice.equalsIgnoreCase("tire")) {
            return new TireFactory();
        } else if (choice.equalsIgnoreCase("engine")) {
            return new EngineFactory();
        }
        return null;
    }
}

public class Test {
    public static void main(String[] args) {
        CarFactory tire = FactoryProducer.getFactory("tire");
        Tire bmw = tire.createTire("bmw");
        bmw.productTire();

        CarFactory engine = FactoryProducer.getFactory("engine");
        Engine benz = engine.createEngine("benz");
        benz.turnOn();
    }
}

工厂模式和抽象工厂模式都是创建型模式的代表,唯一区别在于需要根据场景复杂程度来决定使用场景,当系统内产品数量相对较少,且呈复杂增长的趋势较小,应选择工厂模式;若系统内产品相对较为复杂,且对象增长趋势难以确定,应选择抽象工厂模式进行产品抽象,方便应对复杂变化。

抽象工厂模式优点: 保证多个对象能协同工作,同时保证获取到的产品属于同一个产品族;

抽象工厂模式缺点:扩展相对较为困难,当新增产品时,需要修改抽象工厂类,同时还有添加具体产品获取代码,在一定程度上违反开闭原则。

3.小结

1.工厂模式和抽象工厂模式都是创建型模式;
2.模式的使用都是基于场景进行选择,没有银弹。

4.参考文献

1.《设计模式-可复用面向对象软件的基础》-Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides
2.《可复用物联网Web3D框架的设计与实现》-程亮(知网)
3.https://www.bilibili.com/video/BV1G4411c7N4-尚硅谷设计模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值