[设计模式]工厂模式

开始写设计模式系列,希望自己可以坚持下来.
第四篇:工厂模式

我们通常使用new来创建一个新的对象,但是也随之带来一系列问题,比如,许多复杂对象的创建需要一定的步骤,在创建对象的时候需要依赖别的对象,直接在ClassA 中创建ClassB的对象,那么代码的耦合强太高。

什么是工厂模式

工厂模式分为:

  • 简单工厂模式(静态工厂模式)
  • 工厂方法模式
  • 抽象工厂模式

那他们三有什么区别呢?


  • 简单工厂模式:
    一个抽象产品类,可以派生出多个具体产品类。
    一个工厂类。
    工厂类只能创建指定具体产品类的实例。

  • 工厂方法模式:
    一个抽象产品类,可以派生出多个具体产品类。
    一个抽象工厂类,可以派生出多个具体工厂类。
    每个具体工厂类只能创建一个具体产品类的实例。

  • 抽象工厂模式:
    多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
    一个抽象工厂类,可以派生出多个具体工厂类。
    每个具体工厂类可以创建多个具体产品类的实例。

他们三是从上而下逐步抽象的过程。

简单工厂模式

小王开了一家奥迪生产车间,主要生产奥迪的Q系列Q3,Q5,Q7,小王知道他们三款的组装其实大致相同,其中最为主要的工作就是组装发动机,安装汽车剩余配件,安装汽车系统软件。

package top.huyuxin.factorymodel;

public abstract class AudiProduct {

    abstract void installengine();

    abstract void installfitting();

    abstract void installsoftware();

}

Q3:

package top.huyuxin.factorymodel;

public class AudiQ3 extends AudiProduct {

    @Override
    void installengine() {
        System.out.println("Q3:installengine");
    }

    @Override
    void installfitting() {
        System.out.println("Q3:installfitting");
    }

    @Override
    void installsoftware() {
        System.out.println("Q3:installsoftware");
    }

}

Q5:

package top.huyuxin.factorymodel;

public class AudiQ5 extends AudiProduct {

    @Override
    void installengine() {
        System.out.println("Q5:installengine");
    }

    @Override
    void installfitting() {
        System.out.println("Q5:installfitting");
    }

    @Override
    void installsoftware() {
        System.out.println("Q5:installsoftware");
    }
}

Q7:

package top.huyuxin.factorymodel;

public class AudiQ7 extends AudiProduct {

    @Override
    void installengine() {
        System.out.println("Q7:installengine");
    }

    @Override
    void installfitting() {
        System.out.println("Q7:installfitting");
    }

    @Override
    void installsoftware() {
        System.out.println("Q7:installsoftware");
    }
}

这样我们还需要一个工厂来生产这些产品:

package top.huyuxin.factorymodel;

public class AudiFactory {
    enum CarType{
        AudiQ3,
        AudiQ5,
        AudiQ7
    };

    public static AudiProduct createAudiCar(CarType carType){
        AudiProduct audiProduct = null;
        switch (carType) {
        case AudiQ3:
            audiProduct=new AudiQ3();
            break;
        case AudiQ5:
            audiProduct=new AudiQ5();
            break;
        case AudiQ7:
            audiProduct=new AudiQ7();
            break;
        default:
            break;
        }
        return audiProduct;
    }

}

在使用过程中:

    public static void main(String[] args) {

        AudiProduct audiCarQ3 = AudiFactory.createAudiCar(CarType.AudiQ3);
        audiCarQ3.installengine();
        audiCarQ3.installfitting();
        audiCarQ3.installsoftware();
    }

结果:

Q3:installengine
Q3:installfitting
Q3:installsoftware

但是这样的实现还是不够优雅,因为当有产品增加的时候,工厂类需要修改增加一个case,这是让人不能忍受的,所以需要反射泛型来帮忙,重写AudiFactory:

package top.huyuxin.factorymodel;

public class AudiFactory {

    public static <T extends AudiProduct> T createAudiCar( Class<T> clazz){

        AudiProduct audiProduct = null;
        try {
            audiProduct = (T) Class.forName(clazz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T) audiProduct;
    }
}

使用:

    public static void main(String[] args) {

        AudiProduct audiCarQ3 = AudiFactory.createAudiCar(AudiQ3.class);
        audiCarQ3.installengine();
        audiCarQ3.installfitting();
        audiCarQ3.installsoftware();
    }

这样下次即使有同类产品增加,创建产品类继承AudiProduct,在使用工厂创建的时候只要传入类类型就可以了。

工厂方法模式

工厂方法模式与简单工厂模式的区别在于抽象的工厂类,我们抽象出一个工厂Factory并使用之前泛的简单工厂模式进一步泛化:

package top.huyuxin.factorymodel;

public abstract class Factory<T> {


}

重写AudiFactory

package top.huyuxin.factorymodel;

public class AudiFactory<T extends AudiProduct> extends Factory<T>{


    public <T extends AudiProduct>T createCar(Class<T> clazz){

        AudiProduct audiProduct = null;
        try {
            audiProduct = (AudiProduct) Class.forName(clazz.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return  (T) audiProduct;
    }
}

我们从这可以看出这给以后其他工厂的扩展带来了可能性,也就是引入了工厂的抽象类,下一次我们就可以创建BenzFactory,BMWFactory,这给生产线带来了无限的可能,我们来看下现在泛化的AudiFactory使用,

    public static void main(String[] args) {
        //创建对应的工厂
        AudiFactory<AudiProduct> audiFactory=new AudiFactory<>();
        //创建工厂里的对应的产品
        AudiQ3 audiQ3 = audiFactory.createCar(AudiQ3.class);
        audiQ3.installengine();
        audiQ3.installfitting();
        audiQ3.installsoftware();
    }

抽象工厂模式

抽象工厂模式与工厂模式的区别在与抽象产品的多样性以及每个工厂需要创建多个工厂的实例。
简单来说就是工厂应当能够创建多种类型的产品
,其实我们在对工厂方法模式泛化打的时候就已经利用泛型顺带实现了单一工厂的多种产品的创建。如果需要创建不同类型的产品引入新的抽象产品类以及具体的产品类即可,实现方法同理,这里抽象工厂模式不再赘述。
优点:
大大的降低了同一类型的对象创建时对于宿主对象的耦合度。对于客户端无需知道具体实现内容,只需面向接口编程即可。
缺点:
类数量爆炸式增长,当抽象产品类需要改动,工作量较大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值