通过王者荣耀学习抽象工厂方法模式

文章类别 in java, 设计模式

说起王者荣耀,之前有一段时间我掉进了这个坑之后,久久不能自拔,每天至少要撸上好几盘才肯罢休。 为了段位,不断的去打排位上分,现在已经跳出这个坑了,很少去玩了,除非跟朋友无聊会一起开一下黑! 可是,今天要说的抽象工厂方法的设计模式和王者荣耀要什么关系呢?

别着急,听我慢慢瞎扯即可!

产品等级结构

我们都知道王者荣耀里面的角色类型有好几种,比如:坦克,刺客,法师,射手,辅助…

  • 坦克有:张飞,程咬金,刘禅等等
  • 刺客有:李白,阿珂,赵云等等
  • 法师有:安其拉,貂蝉(说到貂蝉我就流口水),妲己等等。 …

我们可以把这种继承关系看成一个产品等级结构

我们刚刚说的 “坦克有:张飞,程咬金,刘禅等等” 就是一个产品等级结构……

可以理解为张飞,程咬金,刘禅继承于坦克,所以这个体系就是一个等级结构!

像这样就可以看成是一个产品等级结构:

Vimium

产品族

我们知道,在王者荣耀这些角色中,有男也有女,也有怪物: - 男:韩信,李白,张飞,吕布… - 女:不知火舞,貂蝉,安其拉… - 怪物:猴子,牛魔…

这些角色中不在同一产品等级结构中,例如不知火舞是刺客,安其拉是法师。但是他们却有共同的属性,例不知火舞和安其拉都是女的。 所以我们可以认为他们是一个族,也就是产品族

抽象工厂方法模式

我们已经知道产品等级结构和产品族是什么了,那么接下来就可以说说抽象工厂方法模式。

在抽象工厂方法模式里边,每一个工厂都提供了多个工厂方法,用来产生多种不同的类型的产品,而这些产品就构成了一个产品族。

例如有一个工厂,产生了不知火舞和安其拉,他们属于不同类型的角色,但是他们都是女的,工厂产生的这两个人物就构成了女的这个族! 这就是工厂方法模式的基本原理。

抽象工厂方法模式的定义是:“提供接口,创建一系列相关或独立的对象,而不指定这些对象的具体类。”

画个uml你就明白了:

抽象工厂方法模式

可以看到:

  1. AbstractFactory抽象工厂:它声明创建了产品族的接口,每一个方法对应一个产品,在这里我的产品族就是“男族”和“女族”,第一个方法创造的是法师,第二个 方法创造的是刺客。

  2. GirlFactory和BoyFactory具体工厂:它们实现了抽象工厂,产生具体的产品,这里的GirlFactory产生了安其拉和阿珂,组成的就是一个产品族:“女族”, BoyFactory产生了诸葛亮和赵云,组成了一个产品族:“男族”,而GirlFactory和BoyFactory产生的每个产品都位于不同的产品等级结构中,比如 这里的GirlFactory产生了安其拉和阿珂,安其拉是在法师这个“产品等级结构”中,阿珂是在刺客这个“产品等级结构”中!

  3. AbstractFashi和AbstractCiKe抽象产品:声明产品的接口,声明产品具有的业务方法,例如这里的AbstractFashi声明了法师,定义一些法师的功能。

  4. AnQiLa,ZhuGeLiang,Ake,ZhaoYun 具体产品:实现了抽象产品,实现相关的业务方法。

我们用代码来体现一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
 * Created by wistbean on 2017/11/22.
 * 抽象产品 法师
 */
public interface AbstractFashi {
  ra  //加蓝
    public void jiaLan();
}

/**
 * Created by wistbean on 2017/11/22.
 * 具体产品  安其拉
 */
public class AnQiLa implements AbstractFashi {
    @Override
    public void jiaLan() {
        System.out.println("安其拉加蓝咯");
    }
}


/**
 * Created by wistbean on 2017/11/22.
 * 具体产品 诸葛亮
 */
public class ZhuGeLiang implements AbstractFashi {
    @Override
    public void jiaLan() {
        System.out.println("诸葛亮加蓝咯!");
    }
}


/**
 * Created by wistbean on 2017/11/22.
 * 抽象产品 刺客
 */
public interface AbstractCiKe {
    //加伤害
    public void jiaShanHai();
}


/**
 * Created by wistbean on 2017/11/22.
 * 具体产品 阿珂
 */
public class AKe implements AbstractCiKe {
    @Override
    public void jiaShanHai() {
        System.out.println("阿珂加伤害了");
    }
}


/**
 * Created by wistbean on 2017/11/22.
 * 具体产品 赵云
 */
public class ZhaoYun implements AbstractCiKe {
    @Override
    public void jiaShanHai() {
        System.out.println("赵云加伤害咯!");
    }
}


/**
 * Created by wistbean on 2017/11/22.
 * 抽象工厂 声明一组创建产品族的方法
 */
 public interface AbstractFactory {
    AbstractFashi createFashi();
    AbstractCiKe createCiKe();
}


/**
 * Created by wistbean on 2017/11/22.
 * 具体工厂 实现抽象工厂的方法,生成具体产品 构成产品族
 */
public class BoyFactory implements AbstractFactory {
    @Override
    public AbstractFashi createFashi() {
        return new ZhuGeLiang();
    }

    @Override
    public AbstractCiKe createCiKe() {
        return new ZhaoYun();
    }
}


/**
 * Created by wistbean on 2017/11/22.
 * 具体工厂 实现抽象工厂的方法,生成具体产品 构成产品族
 */
public class GirlFactory implements AbstractFactory {
    @Override
    public AbstractFashi createFashi() {
        return new AnQiLa();
    }

    @Override
    public AbstractCiKe createCiKe() {
        return new AKe();
    }
}


public class Client {
    public static void main(String[] args){
        //要从工厂里边取女的人物
         AbstractFactory girlFactory;
         AbstractCiKe ciKe;
         AbstractFashi fashi;
        //获取工厂
        girlFactory = new GirlFactory();
        //获取刺客中女的人物
        ciKe = girlFactory.createCiKe();
        //获取法师中女的人物
        fashi = girlFactory.createFashi();

        ciKe.jiaShanHai();
        fashi.jiaLan();
    }
}

输出:
阿珂加伤害了
安其拉加蓝咯

抽象工厂方法模式和工厂方法模式的区别

以上就是抽象工厂方法模式的实现,我们可以看到它和工厂方法模式的区别:

工厂方法模式中的工厂对应一类产品,我们有许多产品需要创建的时候就会增加许多相应的工厂,会增加系统的 开销,而抽象工厂方法模式是将一些相关的产品(产品族)使用同一个工厂就可以创建。减少了系统的开销。

工厂方法模式只是针对一个产品等级结构,而抽象工厂可以同时针对多个产品等级结构,所以当我们需要一个工厂 来创建不同等级结构的一个产品族的所有对象的时候,抽象工厂方法模式比工厂方法模式更加的高效!

抽象工厂方法模式的优缺点

优点

  1. 增加新的产品族的时候非常方便,我们只需要对抽象工厂进行扩展就可以了,不需要修改系统本身的其它东西。
  2. 对统一约束产品有很好的解决方式,尽管产品之间没有很大的联系,但是它们都属于同一个操作系统中,可以 对其进行很好的规范约束!
  3. 用户无需关心对象的创建过程,低耦合!

缺点

如果我们要增加新的产品结构,那对系统的扩展来说会是比较麻烦的,需要对系统里边的代码进行修改,带来不便, 违背了设计模式中的开闭原则

抽象工厂方法模式的使用场景

  1. 同一产品族的产品被系统一起使用
  2. 不需要知道产品是如何被创建的
  3. 产品等级结构设计稳定,后续只增加产品族

我的相关文章