Java设计模式之工厂模式

本文总结一下java的GOF(Gang Of Four)23种设计模式中的工厂模式。

工厂模式:

作用:实现了创建者和调用者的分离;

核心本质:实例化对象,用工厂方法代替new操作,将选择实现类创建对象统一管理和控制,从而将调用者跟我们的实现类解耦。

工厂设计的基本原则:

1、OCP(Open_Closed Principle):开闭原则,一个软件的实体类应当对扩展开放,对修改关闭;

2、DIP(Dependence Inversion Principle):依赖倒转原则,要针对接口编程,不要针对实现编程;

3、LOD(Law Of Demeter):迪米特法则,只与你直接的朋友通信,避免和陌生人通信。

分类:

1、简单工厂模式(Simple Factory)

2、工厂方法模式(Factory Method)

3、抽象工厂模式(Abstract Factory)

一 简单工厂模式

  用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有的代码)

  例:

手机接口

1 public interface Phone {
2     void create();
3 }

实现手机接口的类(假设分别为华为手机和小米手机)

1 public class HuaWei implements Phone{
2     @Override
3     public void create() {
4         System.out.println("这是华为手机");
5     }
6 }
1 public class Mi implements Phone{
2     @Override
3     public void create() {
4         System.out.println("这是小米手机");
5     }
6 }

创建简单工厂类(实例化HuaWei类和Mi类)。这里可以使用两种方法,如下:

第一种

 1 public class SimpleFactory {
 2 
 3     public static Phone createHuaWei(){
 4         return new HuaWei();
 5     }
 6 
 7     public static Phone createMi(){
 8         return new Mi();
 9     }
10 }

第二种

 1 public class SimpleFactory1 {
 2 
 3     public static Phone createPhone(String type){
 4         if (type.equals("华为")){
 5             return new HuaWei();
 6         }else if (type.equals("小米")){
 7             return new Mi();
 8         }else{
 9             return null;    //防止空指针
10         }
11     }
12 }

测试类

 1 public class TestSimpleFactory {
 2     public static void main(String[] args) {
 3         //这是测试第一种的代码
 4         Phone phone1 = SimpleFactory.createHuaWei();
 5         Phone phone2 = SimpleFactory.createMi();
 6 
 7         phone1.create();
 8         phone2.create();
 9         //这是测试第二种的代码
10         Phone phone3 = SimpleFactory1.createPhone("华为");
11         Phone phone4 = SimpleFactory1.createPhone("小米");
12 
13         if (phone3 != null) {
14             phone3.create();
15         }
16         if (phone4 != null) {
17             phone4.create();
18         }
19     }
20 }

打印结构

这是华为手机
这是小米手机
这是华为手机
这是小米手机

  简单工厂模式也叫静态工厂模式,就是因为工厂类一般使用静态方法,通过接收的参数的不同来返回不同的对象实例。  

  假设你还要增加一个vivo手机的话,就需要增加一个实现手机接口的类以及在简单工厂类中添加一个方法或者添加一个判定条件(else if(type.equals("vivo"))即可。如果不能修改代码的话,这种工厂模式就不能扩展,所以为了更好的增加产品,就可以使用工厂方法模式。

二 工厂方法模式

  用来生产同一等级结构中的固定产品。(支持增加任意产品)

电脑接口

1 public interface Computer {
2     void create();
3 }

实现电脑接口的类(假设有联想电脑和华硕电脑)

1 public class LianXiang implements Computer {
2     @Override
3     public void create() {
4         System.out.println("这是联想电脑");
5     }
6 }
1 public class HuaShuo implements Computer {
2     @Override
3     public void create() {
4         System.out.println("这是华硕电脑");
5     }
6 }

先创建一个工厂接口,再为每类电脑都创建一个工厂类实现这个工厂接口

1 public interface FactoryMethod {  
2     Computer factory();
3 }
1 //实现工厂接口的联想工厂类
2 public class LianXiangFactory implements FactoryMethod {
3     @Override
4     public Computer factory() {
5         return new LianXiang();
6     }
7 }
1 //实现工厂接口的华硕工厂类
2 public class HuaShuoFactory implements FactoryMethod {
3     @Override
4     public Computer factory() {
5         return new HuaShuo();
6     }
7 }

测试类

1 public class TestFactoryMethod {
2     public static void main(String[] args) {
3         Computer computer1 = new LianXiangFactory().factory();
4         Computer computer2 = new HuaShuoFactory().factory();
5 
6         computer1.create();
7         computer2.create();
8     }
9 }

测试结果

这是联想电脑
这是华硕电脑

  工厂方法模式和简单工厂模式最大的不同在于简单工厂模式只有一个工厂类,而工厂方法模式则是有多个实现了相同接口的工厂类(每个工厂类对应一个产品)。

  这种模式下想要增加产品时,可以直接添加一个产品类和对应的产品工厂类(并实现工厂接口)。不需要更改其它代码。

三 抽象工厂模式

  用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)

  这里多了一个概念——产品族,假设一个产品为屏幕,一个产品为键盘,一个产品为鼠标;那么这个产品族我们就可以理解为电脑。所以我们接下来的例子可以这样假设,如果屏幕,键盘,鼠标都是内置的——笔记本电脑;而屏幕,键盘,鼠标都市外置的——台式电脑。那么代码如下:

创建三个产品(一个产品接口和实现产品接口的其他类)

 1 //屏幕接口
 2 public interface Display {
 3     void view();
 4 }
 5 //内置屏幕
 6 class InnerDisplay implements Display{
 7     @Override
 8     public void view() {
 9         System.out.println("这是内置屏幕");
10     }
11 }
12 //外接屏幕
13 class OuterDisplay implements Display{
14     @Override
15     public void view() {
16         System.out.println("这是外接屏幕");
17     }
18 }
 1 //键盘接口
 2 public interface KeyBoard {
 3     void play();
 4 }
 5 //内置键盘
 6 class InnerKeyBoard implements KeyBoard{
 7     @Override
 8     public void play() {
 9         System.out.println("这是内置键盘");
10     }
11 }
12 //外接键盘
13 class OuterKeyBoard implements KeyBoard{
14     @Override
15     public void play() {
16         System.out.println("这是外置键盘");
17     }
18 }
 1 //鼠标接口
 2 public interface Mouse {
 3     void check();
 4 }
 5 //内置鼠标
 6 class InnerMouse implements Mouse{
 7     @Override
 8     public void check() {
 9         System.out.println("这是内置鼠标");
10     }
11 }
12 //外接鼠标
13 class OuterMouse implements Mouse{
14     @Override
15     public void check() {
16         System.out.println("这是外置鼠标");
17     }
18 }

创建一个工厂接口

1 public interface AbstractFactory {
2     Display createDisplay();    //用于实例化Display类
3     KeyBoard createKeyBoard();  //用于实例化KeyBoard类
4     Mouse createMouse();        //用于实例化Morse类
5 }

创建一个工厂类实例化内置屏幕类,内置键盘类,内置鼠标类,并实现工厂接口

 1 public class AbstractFactoryImpl01 implements AbstractFactory {
 2     //实例化内置屏幕
 3     @Override
 4     public Display createDisplay() {
 5         return new InnerDisplay();
 6     }
 7     //实例化内置键盘
 8     @Override
 9     public KeyBoard createKeyBoard() {
10         return new InnerKeyBoard();
11     }
12     //实例化内置鼠标
13     @Override
14     public Mouse createMouse() {
15         return new InnerMouse();
16     }
17 }

再创建一个工厂类实例化外接屏幕类,外接键盘类,外接鼠标类,并实现工厂接口

 1 public class AbstractFactoryImpl02 implements AbstractFactory {
 2     //实话外接屏幕
 3     @Override
 4     public Display createDisplay() {
 5         return new OuterDisplay();
 6     }
 7     //实例化外接键盘
 8     @Override
 9     public KeyBoard createKeyBoard() {
10         return new OuterKeyBoard();
11     }
12     //实例化外接鼠标
13     @Override
14     public Mouse createMouse() {
15         return new OuterMouse();
16     }
17 }

  通过这个例子可以看出抽象工厂模式和工厂方法模式很相似,其实抽象工厂模式是工厂方法模式的升级版本,在有多个产品品种,产品分类时通过抽象工厂模式产生需要的对象是一种非常好的解决方式。

应用场景

  1. JDBC中Connection对象的获取;
  2. Hibernate中SessionFactory创建Session;
  3. 反射中Class对象的newInstance();
  4. JDK中Calender的getInstance()方法;
  5. ... ...

结语

  上面就是工厂设计模式的三种模式,之所以每种模式都使用了一种例子,也是为了加强自己的练习和能力。图片也是自己画的,希望大家能够理解。

 

posted @ 2019-08-04 22:06  雨很安静  阅读(385)  评论(0编辑  收藏  举报