Java设计模式之工厂模式(简单工厂模式和工厂方法模式)

简单工厂模式

简单工厂模式(Simple factory pattern):是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。

简单工厂模式什么场景下合适呢?现在举个形象的例子,最近国产豪车WEI蛮火的,就拿这个来说。

长城WEI现在就生产两个型号的车vv5、vv7。那么就先建立一个总的生产适用接口
这里写图片描述

直接代码演示:

/**
 * 长城的WEI生产线接口
 * @author Layne
 */
public interface WEIFactory {
    public boolean production(String username, int price);

}

vv5的生产类:

/**
 * vv5的生产线
 * @author Layne
 */
public class VV5Factory implements WEIFactory {

    @Override
    public boolean production(String username, int price) {
        System.out.println("vv5工厂生产一部WEI vv5,由"+username+"花费"+price+"购买");
        return true;
    }

}

vv7的生产类:

/**
 * vv7的生厂线
 * @author Layne
 */
public class VV7Factory implements WEIFactory {

    @Override
    public boolean production(String username, int price) {
        System.out.println("vv7工厂生产一部WEI vv7,由"+username+"花费"+price+"购买");
        return true;
    }

}

简单的工厂类:这里就需要一个简单的工厂类FactoryManager,根据调用者的不同要求,创建出不同的生产类对象并返回。如果有不合法的要求,就返回一个异常。

/**
 * 工厂类
 * @author Layne
 */
public class FactoryManager {
    public static WEIFactory factory(String type) {
        if (type.equals("vv5")) {
            System.out.println("您想购买的是WEI vv5");
            return new VV5Factory();
        } else if (type.equals("vv7")) {
            System.out.println("您想购买的是WEI vv7");
            return new VV7Factory();
        } else {
            // 抛出一个异常
            throw new RuntimeException("没有找到您想购买的车型");
        }
    }
}

测试类:

/**
 * 测试类
 * @author Layne
 */
public class Test {
    public static void main(String[] args) {
        String carType = "vv7";
        String name = "layne";
        int price = 200000;
        WEIFactory weiFactory = FactoryManager.factory(carType);
        boolean success = weiFactory.production(name, price);
        if (success) {
            System.out.println("购买成功");
        } else {
            System.out.println("购买失败");
        }
    }
}

运行结果:
这里写图片描述

简单工厂模式总结:
优点:
模式的核心是工厂类。这个类含有必要的逻辑判断,可以决定在什么时候创建哪一个生产类的实例并返回,而调用者则可以免除直接创建对象的责任。简单工厂模式通过这种做法实现了对责任的风格,当长城开发新型号汽车的时候无需修改调用者。

缺点:
这个工厂类集中了所有创建逻辑,当有复杂的、多层次的、多结构的逻辑时,所有的业务逻辑都会在这个工厂类中实现。当这个类崩溃时,整个系统都会受到影响。




工厂方法模式

工厂方法模式(factory method pattern): 定义了一个创建对象的接口, 但由子类决定要实例化的类是哪一个. 工厂方法让类把实例化推迟到子类.

工厂方法模式又是什么场景下合适呢?就拿上面那个例子来延伸。

现在的需求只是vv5、和vv7两种车型,工厂类就需要两个if来判断了。假如每个车型再分为标准版、尊贵版,那么就要4个if来判断。如果日后不断创新车型和版本,那么后果就不堪设想了。

这时候就需要工厂方法模型来处理以上的需求了,在工厂方法模式中,核心的工厂类不在负责所有的对象的创建,而是将具体创建的工作交给子类去做。这个核心类则摇身一变,成为了一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪个类应当被实例化这种细节。

这种进一步的抽象结果,使这种工厂方法模式可以用来允许系统在不修改具体工厂角色的情况下引进新的产品,这一特点无疑使得工厂方法模式具有超过简单工厂模式的优越性。
这里写图片描述

抽象工厂角色:

/**
 * 抽象工厂角色
 * @author Layne
 */
public interface WEIFactory {
    public Version factory(String type);

}

具体工厂角色类,vv5的具体工厂:

/**
 * vv5具体工厂角色
 * 
 * @author Layne
 */
public class VV5Factory implements WEIFactory {

    @Override
    public Version factory(String type) {
        if (type.equals("standard")) {
            System.out.println("您选择的是标准版的vv5");
            return new VV5StandardVersion();

        } else if (type.equals("honorable")) {
            System.out.println("您选择的是尊贵版的vv5");
            return new VV5HonorableVersion();

        } else {
            throw new RuntimeException("没有找到您想购买的型号");
        }
    }

}

vv7的具体工厂:

/**
 * vv7具体工厂角色
 * @author Layne
 */
public class VV7Factory implements WEIFactory {

    @Override
    public Version factory(String type) {
        if (type.equals("standard")) {
            System.out.println("您选择的是标准版的vv7");
            return new VV7StandardVersion();

        } else if (type.equals("honorable")) {
            System.out.println("您选择的是尊贵版的vv7");
            return new VV7HonorableVersion();

        } else {
            throw new RuntimeException("没有找到您想购买的型号");
        }
    }


}

抽象版本生产类:

/**
 * 抽象版本生产类
 * @author Layne
 *
 */
public interface Version {
    public boolean production(String username, int price);
}

具体生产角色类,通常情况下这个类会有复杂的业务逻辑。
vv5标准版:

/**
 * 生产vv5标准版类
 * @author Layne
 *
 */
public class VV5StandardVersion implements Version {

    @Override
    public boolean production(String username, int price) {
        System.out.println("生产一部标准版vv5,由"+username+"花费"+price+"购买");
        return true;
    }

}

vv5尊贵版:

/**
 * 生产vv5尊贵版类
 * @author Layne
 *
 */
public class VV5HonorableVersion implements Version {

    @Override
    public boolean production(String username, int price) {
        System.out.println("生产一部尊贵版vv5,由"+username+"花费"+price+"购买");
        return true;
    }

}

vv7标准版:

/**
 * 生产vv7标准版类
 * @author Layne
 *
 */
public class VV7StandardVersion implements Version {

    @Override
    public boolean production(String username, int price) {
        System.out.println("生产一部标准版vv7,由"+username+"花费"+price+"购买");
        return true;
    }

}

vv7尊贵版:

/**
 * 生产vv7尊贵版类
 * @author Layne
 *
 */
public class VV7HonorableVersion implements Version {

    @Override
    public boolean production(String username, int price) {
        System.out.println("生产一部尊贵版vv7,由"+username+"花费"+price+"购买");
        return true;
    }

}

测试类:

/**
 * 测试类
 * @author Layne
 *
 */
public class Test {
    public static void main(String[] args) {
        String version1 = "standard";
        String version2 = "honorable";

        String name = "Layne";
        int price = 200000;

        WEIFactory vv7Factory = new VV7Factory();
        Version version = vv7Factory.factory(version2);
        boolean success = version.production(name, price);
        if (success) {
            System.out.println("购买成功");
        } else {
            System.out.println("购买失败");
        }
    }
}

运行结果:
这里写图片描述

工厂方法模式和简单工厂模式
工厂方法模式和简单工厂模式在结构上的不同很明显。工厂方法模式的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。

工厂方法模式退化后可以变得很想简单工厂模式。设想如果非常确定一个系统只需要一个具体工厂类,那么不妨把抽象工厂合并到具体工厂类中去。由于自由一个具体工厂类,所以不妨将工厂方法改为静态方法,这时候就得到了简单工厂模式。

如果系统需要加入新的车型,那么所需要的就是想系统中加入一个这样的版本类以及所对应的工厂类就行了,没必要修改客户端,也没有必要修改抽象工厂角色或者其他已有的具体工厂角色。对于增加新的车型而言,这个系统完全支持“开-闭原则”。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值