工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

工厂模式分为:

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

简单工厂模式:

首先常见一个Car接口,接口中定义一个run()方法:

1 package top.bigking.factory.simpleFactory;
2 
3 /**
4  * @Author ABKing
5  * @Date 2020/2/7 下午3:43
6  **/
7 public interface Car {
8     public void run();
9 }

再写两个类实现这个Car接口

 1 package top.bigking.factory.simpleFactory;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/7 下午3:44
 6  **/
 7 public class Benchi implements Car {
 8     @Override
 9     public void run() {
10         System.out.println("奔驰");
11     }
12 }
 1 package top.bigking.factory.simpleFactory;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/7 下午3:44
 6  **/
 7 public class Byd implements Car {
 8     @Override
 9     public void run() {
10         System.out.println("比亚迪");
11     }
12 }

测试如下:

 1 /**
 2  * @Author ABKing
 3  * @Date 2020/2/7 下午3:45
 4  **/
 5 public class TestSimpleFactory {
 6     @Test
 7     public void testNoFactory(){
 8         Car car1 = new Benchi();
 9         Car car2 = new Byd();
10         car1.run();
11         car2.run();
12 
13 
14     }
15 }

很明显我们可以看到,作为用户来讲,必须知道接口,还要知道实现类。

而我们不希望用户知道这么多,我们需要隐藏这些,由此,我们引入了简单工厂模式:

新建一个工厂类:

 1 package top.bigking.factory.simpleFactory;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/7 下午3:48
 6  **/
 7 public class CarFactory {
 8     public Car getCar(String carName){
 9         if(carName.equals("奔驰")){
10             return new Benchi();
11         }
12         else if(carName.equals("比亚迪")){
13             return new Byd();
14         }
15         return null;
16     }
17 }

进行测试:

 1 package top.bigking.factory.simpleFactory;
 2 
 3 import org.junit.Test;
 4 import sun.security.krb5.internal.ccache.CCacheInputStream;
 5 
 6 /**
 7  * @Author ABKing
 8  * @Date 2020/2/7 下午3:45
 9  **/
10 public class TestSimpleFactory {
11     @Test
12     public void testNoFactory(){
13         Car car1 = new Benchi();
14         Car car2 = new Byd();
15         car1.run();
16         car2.run();
17     }
18     @Test
19     public void testCarFactory(){
20         CarFactory carFactory = new CarFactory();
21         Car car1 = carFactory.getCar("比亚迪");
22         Car car2 = carFactory.getCar("奔驰");
23         car1.run();
24         car2.run();
25     }
26 }

这样用户就不必知道具体的实现了,只需要知道相应的接口即可。

但是我们应该注意的是:如果我们需要增加新的车,比如兰博基尼,我们就需要添加一个新的类,并且在修改工厂类

这显然违反了 开闭原则(对扩展开放,对修改关闭)。

所以我们引入了新的工厂模式:

工厂方法模式

把工厂中的方法抽象出来,形成新的类,BenchiFactory和BydFactory

同时,由于这两个类具有相同的抽象意义,我们定义一个接口,CarFactory

1 package top.bigking.factory.factoryMethod;
2 
3 /**
4  * @Author ABKing
5  * @Date 2020/2/10 下午5:28
6  **/
7 public interface CarFactory {
8     public Car getCar();
9 }
 1 package top.bigking.factory.factoryMethod;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/10 下午5:25
 6  **/
 7 public class BenchiFactory implements CarFactory{
 8     @Override
 9     public Car getCar() {
10         return new Benchi();
11     }
12 }
 1 package top.bigking.factory.factoryMethod;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/10 下午5:24
 6  **/
 7 public class BydFactory implements CarFactory{
 8     @Override
 9     public Car getCar() {
10         return new Byd();
11     }
12 }

编写JUnit测试

 1 package top.bigking.factory.factoryMethod;
 2 
 3 import org.junit.Test;
 4 
 5 /**
 6  * @Author ABKing
 7  * @Date 2020/2/10 下午5:27
 8  **/
 9 public class TestFactoryMethod {
10     @Test
11     public void testFactoryMethod(){
12         Car car1 = new BenchiFactory().getCar();
13         Car car2 = new BydFactory().getCar();
14         car1.run();
15         car2.run();
16     }
17 }

工厂方法模式的优点是不需要修改已有的代码,满足开闭原则(对扩展开放,对修改关闭),但是缺点是会增加大量的类,对维护增加了难度。

另外还有一种工厂模式:抽象工厂模式

抽象工厂模式是用来增加产品族的,对增加单个产品无能为力

定义引擎的接口及其实现:

 1 package top.bigking.factory.abstractFactory;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/10 下午10:23
 6  **/
 7 public interface Engine {
 8     public void start();
 9     public void run();
10 }
11 class GoodEngine implements Engine{
12 
13     @Override
14     public void start() {
15         System.out.println("好发动机启动!");
16     }
17 
18     @Override
19     public void run() {
20         System.out.println("好发动机运行");
21     }
22 }
23 class BadEngine implements Engine{
24 
25     @Override
26     public void start() {
27         System.out.println("差发动机启动!");
28     }
29 
30     @Override
31     public void run() {
32         System.out.println("差发动机运行");
33     }
34 }

定义轮胎的接口及其实现

 1 package top.bigking.factory.abstractFactory;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/10 下午10:25
 6  **/
 7 public interface Tyre {
 8     public void roll();
 9 }
10 class GoodTyre implements Tyre{
11     @Override
12     public void roll() {
13         System.out.println("好轮胎滚动");
14     }
15 }
16 class BadTyre implements Tyre{
17     @Override
18     public void roll() {
19         System.out.println("差轮胎滚动");
20     }
21 }

定义工厂接口

 1 package top.bigking.factory.abstractFactory;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/10 下午5:28
 6  **/
 7 public interface CarFactory {
 8     public Engine getEngine();
 9     public Tyre getTyre();
10 }

写工厂的两个实现,好车和差车

 1 package top.bigking.factory.abstractFactory;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/10 下午10:10
 6  **/
 7 public class GoodCarFactory implements CarFactory {
 8 
 9     @Override
10     public Engine getEngine() {
11         return new GoodEngine();
12     }
13 
14     @Override
15     public Tyre getTyre() {
16         return new GoodTyre();
17     }
18 }
 1 package top.bigking.factory.abstractFactory;
 2 
 3 /**
 4  * @Author ABKing
 5  * @Date 2020/2/10 下午10:32
 6  **/
 7 public class BadCarFactory implements CarFactory {
 8     @Override
 9     public Engine getEngine() {
10         return new BadEngine();
11     }
12 
13     @Override
14     public Tyre getTyre() {
15         return new BadTyre();
16     }
17 }

测试代码:

 1 package top.bigking.factory.abstractFactory;
 2 
 3 import org.junit.Test;
 4 
 5 /**
 6  * @Author ABKing
 7  * @Date 2020/2/10 下午10:34
 8  **/
 9 public class TestAbstractFactory {
10     //测试好车
11     @Test
12     public void testGoodCarFactory(){
13         CarFactory carFactory = new GoodCarFactory();
14         Engine engine = carFactory.getEngine();
15         Tyre tyre = carFactory.getTyre();
16         engine.start();
17         engine.run();
18         tyre.roll();
19     }
20     //测试差车
21     @Test
22     public void testBadCarFactory(){
23         CarFactory carFactory = new BadCarFactory();
24         Engine engine = carFactory.getEngine();
25         Tyre tyre = carFactory.getTyre();
26         engine.start();
27         engine.run();
28         tyre.roll();
29     }
30 
31 }
金麟岂是池中物,一遇风云便化龙!
原文地址:https://www.cnblogs.com/ABKing/p/12273383.html