用枚举实现工厂方法模式更简洁

简介:

工厂方法模式(Factory Method Patter)是"创建对象的接口",让子类决定实例化哪一个类,并使一个类的实例化延迟到其子类.工厂方法模式在我们的开发工作中,经常会用到.

下面以汽车制造为例,看看一般的工厂方法模式是如何实现的,代码如下:

复制代码
 1 public class Client {
 2     public static void main(String[] args) {
 3         //生产车辆
 4         Car car = CarFactory.createCar(FordCar.class);
 5     }
 6 }
 7 
 8 //抽象产品
 9 interface Car {
10 };
11 //具体产品类
12 class FordCar implements Car {
13 };
14 //具体产品类
15 class BuickCar implements Car {
16 };
17 //工厂类
18 class CarFactory {
19     //生产汽车
20     public static Car createCar(Class<? extends Car> c) {
21         try {
22             return (Car) c.newInstance();
23         } catch (Exception e) {
24             e.printStackTrace();
25         }
26         return null;
27     }
28 }
复制代码

这是最原始的工厂方法模式,有两个产品"福特骑车和别克骑车,然后通过工厂方法模式来生产,有了工厂方法模式,我们就不用关心一辆车具体是怎么生成的了,只要告诉工厂"给我生产一辆福特骑车"就可以了,下面是产出一辆福特骑车时客户端的代码:

 Car car = CarFactory.createCar(FordCar.class);

这就是我们经常使用的工厂方法模式,但经常使用不代表就是最优秀的,最简洁的.

此处在介绍一种通过枚举实现工厂方法模式的方案,谁优谁劣自行评价.枚举实现工厂方法模式有两种方法:

(1)枚举非静态方法实现工厂方法模式

我们知道每个枚举项都是该枚举的实例对象,那是不是定义一个方法可以生成每个枚举项的对应产品来实现此模式呢?代码如下:

复制代码
 1 public class Client {
 2     public static void main(String[] args) {
 3         //生产汽车
 4         Car car = CarFactory.BuickCar.create();
 5     }
 6 }
 7 
 8 interface Car {
 9 };
10 
11 class FordCar implements Car {
12 };
13 
14 class BuickCar implements Car {
15 };
16 
17 enum CarFactory {
18     //定义工厂类能生产汽车的类型
19     FordCar, BuickCar;
20     //生产汽车
21     public Car create() {
22         switch (this) {
23         case FordCar:
24             return new FordCar();
25         case BuickCar:
26             return new BuickCar();
27         default:
28             throw new AssertionError("无效参数");
29         }
30     }
31 }
复制代码

 create是一个非静态方法,也就是只有通过FordCar,BuickCar枚举项才能访问,采用这种方式实现工厂方法模式时,客户端要产生一辆汽车就很简单了.代码如下:

Car car = CarFactory.BuickCar.create();

 

(2)通过抽象方法生成产品

枚举类型虽然不能继承,但是可以用abstract修饰其方法,此时就标识该枚举是一个抽象枚举,需要每个枚举项自行实现该方法,也就说枚举项的类型是该枚举的一个子类,看代码:

复制代码
 1 public class Client {
 2     public static void main(String[] args) {
 3         Car car = CarFactory.BuickCar.create();
 4     }
 5 }
 6 
 7 interface Car {
 8 };
 9 
10 class FordCar implements Car {
11 };
12 
13 class BuickCar implements Car {
14 };
15 
16 enum CarFactory {
17     FordCar {
18         public Car create() {
19             return new FordCar();
20         }
21     },
22     BuickCar {
23         public Car create() {
24             return new BuickCar();
25         }
26     };
27     //抽象生产方法
28     public abstract Car create();
29 }
复制代码

 

首先定义一个抽象制造方法create,然后 每个枚举项自行实现,这种方式编译后会产生两个CarFactory的匿名子类,因为每个枚举项都 要实现抽象create方法,客户端的调用与上一个方案相同,不再赘述.

为什么使用枚举类型的工厂方法模式有以下三个优点:

(1)避免错误调用的发生

一般工厂方法模式中的生产方法(也就是createCar方法)可以接收三种类型的参数:类型参数(Class),String参数(生产方法中判断String参数是需要生产什么产品),int参数(根据int值判断需要生产什么类型的产品).

这三种参数都是宽泛的数据类型,很容易产生错误.比如边界问题,null值问题,而且出现这类错误编译器还不会报警.例如:

Car car = CarFactory.createCar(Car.class);

 

Car是一个接口,完全合乎createCar方法的要求,所以它在编译时不会报任何错误,但一运行起来就会报java.lang.InstantiationException异常,而使用枚举类型的工厂方法模式就不存在该问题.不需要传递任何参数,只需要选择好生产什么类型的产品就可以了.

(2)性能好,使用便捷.

枚举类型的计算是以int类型的计算为基础的,这是最基本的操作,性能当然快.

(3)降低类间的耦合

不管生产方法接收的是Class,String还是int参数,都会成为客户端类的负担.这些类并不是客户端需要的,而是因为工厂方法的限制必须输入的.******

 



本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/5633233.html,如需转载请自行联系原作者

相关文章
|
9月前
|
设计模式
设计模式小例子理解封装、继承、多态
设计模式小例子理解封装、继承、多态
47 0
|
5月前
|
程序员 C++
代码规范:类的继承与组合
【规则 10-1-2】若在逻辑上 B 是 A 的“一种”(a kind of ),则允许 B 继承 A 的功能和属性。例如男人(Man)是人(Human)的一种,男孩(Boy)是男人的一种。那么类 Man 可以从类 Human 派生,类 Boy 可以从类 Man 派生。
18 0
|
8月前
|
设计模式
26【软件基础】简单计算器的实现+工厂方法模式应用+封装、继承、多态的体现
工厂方法模式是一种常用的`创建型设计模式`,它提供了一种将对象的创建过程封装起来的方法。在工厂方法模式中,将对象的创建过程交给一个`工厂类`来完成,而不是在代码中直接调用构造函数来创建对象。这样可以使得代码更加灵活,`降低耦合度`,方便后期维护和扩展。
90 0
|
11月前
|
设计模式 C#
C# 实例解释面向对象编程中的里氏替换原则
版权声明:本文为CSDN博主「Phil Arist」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_41872328/article/details/123457474
72 0
|
11月前
|
消息中间件 设计模式 JavaScript
为什么我不再推荐枚举策略模式?
为什么我不再推荐枚举策略模式?
|
Java 程序员 编译器
面向对象编程的组合、多态、抽象类的基本介绍(一)
面向对象编程的组合、多态、抽象类的基本介绍
面向对象编程的组合、多态、抽象类的基本介绍(一)
|
编译器
面向对象编程的组合、多态、抽象类的基本介绍(二)
面向对象编程的组合、多态、抽象类的基本介绍
面向对象编程的组合、多态、抽象类的基本介绍(二)
|
设计模式
【重温设计模式】——从工厂方法模式看抽象类和接口的区别
【重温设计模式】——从工厂方法模式看抽象类和接口的区别
95 0
【重温设计模式】——从工厂方法模式看抽象类和接口的区别
|
设计模式 Java Spring
枚举方式实现设计模式-策略模式
枚举方式实现设计模式-策略模式
枚举方式实现设计模式-策略模式
|
设计模式 安全 算法
单例模式的十种写法,你会几个?
单例模式是一种最常见的设计模式,写法也比较多,在这篇文章里面主要是对单例模式的各种写法进行一个介绍。面试的时候会对其中两三种进行体会,而且我还遇到了口述单例模式的例子。重要性就不言而喻了吧。
174 0
单例模式的十种写法,你会几个?