工厂模式(简单工厂,工厂方法,抽象工厂)

  在平常的代码中,难免会去new一个对象,这样调用者与实体类之间就会存在耦合关系,如果创建多个对象调用者就会存在多层耦合关系,而工厂模式就是代替new,实现解耦。工厂模式在我们平常的使用中非常常见,比如 mybatis中的SqlSessionFactory,JDBC中Connection的获取,spring中IOC容器创建管理bean,反射中的newInstance,XML解析时DocumentBuilderFactory创建解析器对象

先举例说明一般的代码,比如我们现在要创建一个奥迪车,创建一个大众车,
两种车的抽象代码:

public interface Car {
    void run();
}
public class Audi implements Car {
    @Override
    public void run() {
        System.out.println("Audi在跑");
    }
}
public class Dazhong implements Car {
    @Override
    public void run() {
        System.out.println("大众在跑");
    }
}

在客户端代码中,我们这样写:

        Car audi = new Audi();
        Car dazhong = new Dazhong();

这样写,该代码块会与两个类耦合

简单工厂模式

  简单工厂模式顾名思义,就是最简单的工厂模式,而工厂就是加工产品的,调用者只需要把提起规范好的要求传给工厂,工厂就可以返回给调用者需要的对象,这里写一个简单工厂类

/**
 *  简单工厂
 */
public class SimpleCarFactory {
    public static Car getCar(String carName) {
        if("audi".equals(carName)) {
            return new Audi();
        } else if("dazhong".equals(carName)) {
            return new Dazhong();
        } else {
            return null;
        }
    }
}

这时调用方的代码就可以这样写:

        Car audi = SimpleCarFactory.getCar("audi");
        Car dazhong = SimpleCarFactory.getCar("dazhong");

可以看到,现在的调用者只与工厂类有耦合关系

但是想一个问题,我们如果要增加一个汽车类-奔驰,那么代码该如何更改,首先我们需要创建一个奔驰类

public class Benchi implements Car {
    @Override
    public void run() {
        System.out.println("奔驰");
    }
}

还要在简单工厂中添加代码

public class SimpleCarFactory {
    public static Car getCar(String carName) {
        if("audi".equals(carName)) {
            return new Audi();
        } else if("dazhong".equals(carName)) {
            return new Dazhong();
        } else if("benchi".equals(carName)) {
            return new Benchi();
        } else {
            return null;
        }
    }
}

这样工厂类SimpleCarFactory就要增加代码了,不符合软件设计的开闭原则

OCP开闭原则:一个软件的实体应当对扩展开放,对修改关闭

这就要引入工厂方法模式

工厂方法模式

工厂方法模式是每一种产品对应一种工厂,所有的工厂都实现了工厂接口

public interface Factory {
    void createCar();
}

奥迪工厂:

public class AudiFactory implements Factory {
    @Override
    public Car createCar() {
        return new Audi();
    }
}

在代码中创建奥迪车就变成了这样

        Car car = new AudiFactory().createCar();

这时,新增加了需求,要增加一辆比亚迪车,工厂方法模式会怎么做
首先,创建比亚迪类

public class Biyadi implements Car {
    @Override
    public void run() {
        System.out.println("byd...");
    }
}

这时候,直接增加一个比亚迪工厂即可,不用修改原来的代码:

public class BiyadiFactory implements Factory {
    @Override
    public Car createCar() {
        return new Biyadi();
    }
}

创建比亚迪车:

        Car car = new BiyadiFactory().createCar();

比较:可以看到,工厂方法模式遵循了开闭原则,稍微比简单工厂模式要复杂一些,但工厂方法模式会随着业务的复杂,类数量越来越多。在平常的代码编写中,我们一般使用简单工厂模式

抽象工厂模式

  工厂方法模式是简单工厂模式的升级版,抽象工厂模式是什么呢?抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂,超级工厂定义了不止生产一种产品,该超级工厂又称为其他工厂的工厂。举个例子,我们现在有一个超级工厂,定义了生产汽车零件,通过超级工厂,可以生产出高配车的工厂,低配车的工厂,高配车的工厂是生产高级零件的,低配车的工厂是生产低配零件的,通过例子来看一下

public interface CarFactory {
    /**
     * 生产 发动机
     * @return
     */
    Engine createEngine();

    /**
     * 生产座椅
     * @return
     */
    Seat createSeat();

    /**
     * 生产轮胎
     * @return
     */
    Tyre createTyre();
}
/**
 *  低配工厂
 */
public class LowCarFactory implements CarFactory {
    @Override
    public Engine createEngine() {
        //生产低配发动机
        return new LowEngine();
    }

    @Override
    public Seat createSeat() {
        //生产低配座椅
        return new LowSeat();
    }

    @Override
    public Tyre createTyre() {
        //生产低配轮胎
        return new LowTyre();
    }
}
/**
 *  高配工厂
 */
public class LuxuryCarFactory implements CarFactory {
    @Override
    public Engine createEngine() {
        //生产 高配 发动机
        return new LuxuryEngine();
    }

    @Override
    public Seat createSeat() {
        //生产 高配 座椅
        return new LuxurySeat();
    }

    @Override
    public Tyre createTyre() {
        //生产 高配 轮胎
        return new LuxuryTyre();
    }
}

抽象工厂模式的特点就是不可以增加产品,增加的是产品族

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值