工厂模式——NWU_LK

工厂模式

基本概念

工厂顾名思义就是可以创建不同产品,该模式用于封装和管理对象的创建,是一种创建型模式。

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式
1. 简单工厂模式

创建生产汽车的接口

public interface Car {
    void make();
}

生产奔驰和生产宝马

class BenChiCar implements Car{
    @Override
    public void make() {
        System.out.println("奔驰");
    }
}
class BaoMaCar implements Car{
    @Override
    public void make() {
        System.out.println("宝马");
    }
}

创建简单工厂类

class CarFactory{
    public static Car makeCar(String carType) {
        if(carType.equalsIgnoreCase("benchi")){
            return new BenChiCar();
        }
        else if(carType.equalsIgnoreCase("baoma")) {
            return new BaoMaCar();
        }
        return null;
    }
}

使用简单工厂类创建对象

public void test(){
    Car benchi = CarFactory.makeCar("benchi");
    Car baoma = CarFactory.makeCar("baoma");
}

因为工厂类中的makeCar方法是静态的,所以也被称为静态工厂。

缺点:
如果要生产新车,比如特斯拉,那么需要对工厂中的代码进行修改。

2. 工厂方法模式

和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂,也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。

创建抽象工厂类

interface AbstractFactory {
    public Car makeCar();
}

创建生产奔驰的工厂和创建生产宝马的工厂

class BenchiFactory implements AbstractFactory{
    @Override
    public Car makeCar() {
        return new BenChiCar();
    }
}
class BaoMaFactory implements AbstractFactory{
    @Override
    public Car makeCar() {
        return new BaoMaCar();
    }
}

利用工厂生产汽车

public void test(){
    BenchiFactory benchiFactory= new BenchiFactory();
    BaoMaFactory baoMaFactory=new BaoMaFactory();
    Car benchi=baoMaFactory.makeCar();
    Car baoma = baoMaFactory.makeCar();
}
3. 抽象工厂模式

抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。

在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。我们依然拿生产汽车的例子来说明他们之间的区别。

现在工厂除了生产汽车之外,也要生产手机。因此定义手机的接口

interface Bike{
    void make();
}

生产奔驰和宝马的自行车

class BenChiBike implements Bike{
    @Override
    public void make() {
        System.out.println("奔驰自行车");
    }
}
class BaoMaBike implements Bike{
    @Override
    public void make() {
        System.out.println("宝马自行车");
    }
}

定义抽象工厂类

interface AbstractFactory {
    Car makeCar();
    Bike makeBike();
}

创建奔驰工厂和宝马工厂

class BenchiFactory implements AbstractFactory{
    @Override
    public Car makeCar() {
        return new BenChiCar();
    }
    @Override
    public Bike makeBike() {
        return new BenChiBike();
    }
}
class BaoMaFactory implements AbstractFactory{
    @Override
    public Car makeCar() {
        return new BaoMaCar();
    }

    @Override
    public Bike makeBike() {
        return new BaoMaBike();
    }
}

使用工厂类分别创建自行车和车

public void test(){
   	BenchiFactory benchiFactory= new BenchiFactory();
    BaoMaFactory baoMaFactory=new BaoMaFactory();
    Car baomacar=baoMaFactory.makeCar();
    Bike baomabike=baoMaFactory.makeBike();
    Car benchicar = benchiFactory.makeCar();
    Bike benchibike = benchiFactory.makeBike();
}

抽象工厂模式的优点: 抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。

抽象工厂模式的缺点: 产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。

4. 拓展——动态工厂

简单工厂模式的缺点就是随着生产Car的增多,需要不断修改代码。如果新加入个特斯拉的话那么需要对工厂类的代码进行修改。为了解决这种问题,利用反射来实现动态工厂。

编写工厂类

class Factory{
    private Factory(){}
    public static Car getCar(String car_name){
        Car car=null;
        try {
            car=(Car)Class.forName(car_name).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return car;
    }
}

利用动态工厂生产宝马车和奔驰车

public void test(){
    Car benchicar = Factory.getCar("包名.BenChiCar");
    Car baomacar = Factory.getCar("包名.BaoMaCar");
}

动态工厂拓展
如果该工厂不仅要生产汽车,还要生产自行车,那么如何进行修改呢?比较笨的方法是在动态工厂类中在加一个getBike的方法。但这有个问题就是如果不断产生新业务就需要不断修改代码。

解决方案:将要返回的接口类型作为参数传入方法。

class Factory{
    private Factory(){}
    public static <T>T getInstance(String name,Class<T> clazz){
        T instance=null;
        try {
            instance=(T)Class.forName(name).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return instance;
    }
}

获取自行车和汽车

public void test(){
    Car benchicar = Factory.getInstance("包名.BenChiCar",Car.class);
    Car baomacar = Factory.getInstance("包名.BaoMaCar",Car.class);
    Bike benchibike=Factory.getInstance("包名.BenChiBike",Bike.class);
    Bike baomabike=Factory.getInstance("包名.BaoMaBike",Bike.class);
}
JAVA中的使用

Calendar类用到了工厂类,用到的是简单工厂模式。
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值