JAVA之设计模式-工厂模式

工厂模式的三种模式分述

在工厂模式开发中,分为三种:普通工厂模式(simple factory)、工厂方法模式(factory method)、抽象工厂模式(abstract factory)

1. 普通工厂模式:

顾名思义,这个模式本身很简单,而且使用在业务较简单的情况下(非绝对),由三小部分组成

1.1 构成

  • 工厂类     包含一定的业务逻辑和判断逻辑,来具体实例化某一功能
  • 具体产品抽象类     产品抽象类具体产品实现类的父类,可以为抽象类 也可以为接口,下面的代码将以接口形式演示
  • 具体产品实现类     工厂类所创建的对象就是此角色的实例。

1.2 代码 实现一个买车的案例

具体产品抽象类 (接口形式)

/**
 * 具体产品抽象类  定义接口
 *
 * @author san.liu
 */
public interface CarAbstract {

    public String getCarName();
}

具体产品实现类

/**
 * 具体产品实现类 (跑车)
 *
 * @author san.liu
 */
public class RunCarAbstractImpl implements CarAbstract {
    public String getCarName() {
        return "我购买的是跑车";
    }
}

工厂类(业务指向)

/**
 * 简单工厂
 *
 * @author san.liu
 */
public class SimpleCarFactory {

    public CarAbstract getCar(Class<?> classt) throws Exception {

        if (SuvCarAbstractImpl.class.getName().equals(classt.getName())) {
            return new SuvCarAbstractImpl();
        }
        if (RunCarAbstractImpl.class.getName().equals(classt.getName())) {
            return new RunCarAbstractImpl();
        } else {
            throw new Exception("指定购车类型ERROR");
        }
    }
}

测试(test)

public static void main(String[] args)throws Exception {
        SimpleCarFactory simpleCarFactory = new SimpleCarFactory();
        CarAbstract carAbstract = simpleCarFactory.getCar(SuvCarAbstractImpl.class);
        System.out.println(carAbstract.getCarName());
    }


log:
    我购买的是SUV

Process finished with exit code 0

上面测试代码中可以看到实例化了一个工厂类(SimpleCarFactory),个人感觉不太好,可以在改造一下,在工厂类添加一个静态方法。

工厂类 (改造后)

/**
 * 简单工厂
 *
 * @author san.liu
 */
public class SimpleCarFactory {

    public static CarAbstract getCar(Class<?> classt) throws Exception {

        if (SuvCarAbstractImpl.class.getName().equals(classt.getName())) {
            return new SuvCarAbstractImpl();
        }
        if (RunCarAbstractImpl.class.getName().equals(classt.getName())) {
            return new RunCarAbstractImpl();
        } else {
            throw new Exception("指定购车类型ERROR");
        }
    }
}

test (改造后)

public static void main(String[] args)throws Exception {
        CarAbstract carAbstract = SimpleCarFactory.getCar(SuvCarAbstractImpl.class);
        System.out.println(carAbstract.getCarName());
    }

log:我购买的是SUV

Process finished with exit code 0

效果是一样的

1.3 结论

使用了简单工厂模式后,我们的程序不在"有病",更加符合现实中的情况;而且客户端免除了直接创建产品对象的责任,而仅仅负责"消费"产品,但是工厂部分好像不太理想,因为每增加一辆车,都要在工厂类中增加相应的商业逻辑和判断逻辑,这显自然是违背开闭原则的。所以引入了工厂方法模式

2.工厂方法模式

2.1构成

  • 抽象工厂类  在基于普通工厂模式的基础上,在工厂类里添加了一个所有工厂的接口。也可以是抽象类,是具体工厂类的父类
  • 具体工厂类  在基于普通工厂模式的基础上,把普通工厂的逻辑拆分为一个个的单元。
  • 抽象产品类  产品抽象类是具体产品实现类的父类,可以为抽象类 也可以为接口,下面的代码将以接口形式演示
  • 具体产品类  具体工厂类所创建的对象就是此角色的实例。

2.2 代码解释 (同上以购车为案例)

抽象工厂

/**
 * 抽象工厂类
 *
 * @author san.liu
 */
public interface CarFactoryAbstract {

   public CarAbstract getCar();
}

具体工厂

/**
 * 具体工厂实现类 (跑车)
 *
 * @author san.liu
 */
public class RunCarFactoryAbstractImpl implements CarFactoryAbstract {

    public CarAbstract getCar() {
        return new RunCarAbstractImpl();
    }
}




/**
 * 具体工厂实现类(SUV)
 *
 * @author san.liu
 */
public class SuvCarFactoryAbstract implements CarFactoryAbstract {
    public CarAbstract getCar() {
        return new SuvCarAbstractImpl();
    }
}

测试 

 public static void main(String[] args)throws Exception {
        // CarAbstract carAbstract = SimpleCarFactory.getCar(SuvCarAbstractImpl.class);
        // System.out.println(carAbstract.getCarName());

        CarFactoryAbstract carFactoryAbstract = new RunCarFactoryAbstractImpl();
        CarAbstract carAbstract = carFactoryAbstract.getCar();
        System.out.println(carAbstract.getCarName());
    }


log:
    我购买的是跑车

Process finished with exit code 0

2.3 结论

如果使用普通工厂模式,新增车型的时候,我们需要修改普通工厂里的工厂类,这不是我们的初衷,也不符合符合开闭原则。但是工厂方法模式完全规避了这种现象,如果新增车型,我们只需要添加具体工厂实现类,以前的代码(车型)我们完全不用修改。所以,工厂方法模式完全符合开闭原则。但是,假设有100种车型,在工厂模式里就需要添加100个具体工厂类,这样显然是不合理的。所以在根据业务的情况下,选择合适的工厂模式。

3.抽象工厂模式

抽象工厂模式就是对工厂方法模式进行抽象,以上面的案例进行展开。跑车和suv属于汽车类,再将汽车以生产国家为单位进行分类,例如中国suv 、中国跑车、日本suv、日本跑车。

3.1构成

产品等级结构:定义一个SUV的抽象类,那么中国suv和日本suv都属于同级产品,也就是该抽象类的子类

产品族:指同一个工厂生产的,位于不同的产品等级结构的一组产品,比如中国跑车、中国SUV

抽象工厂:是一个接口,抽象工厂模式的核心,包含对多个产品等级结构的声明,任何工厂类都必须实现这个接口

具体工厂:是抽象工厂的实现,负责实例化某个产品族中的产品对象。例如中国生产跑车、SUV这些产品

3.2 使用条件

  • 系统中有多个产品族,而系统一次只可能消费其中一族产品
  • 同属于同一个产品族的产品以其使用

3.3总结

看过了前两个模式,对这个模式各个角色之间的协调情况应该心里有个数了,我就不举具体的例子了。只是一定要注意满足使用抽象工厂模式的条件哦,不然即使存在了多个产品树,也存在产品族,但是不能使用的

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值