《王者荣耀》中程序24种设计模式之奥义第三式·抽象工厂模式

110 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

由来

当你还是一个码农的时候,每天都要编写多少行代码每次都要创建很多类的时候,每建立一次给你一点经验值,累计到十级的时候会发现我写了这很多代码为什么不能复用呢?
这时恭喜您进入转职阶段,由码农转成会放魔法的码农。。。(多么吊炸天技能)
觉醒吧!少年。
以王者荣耀为示例题材,写代码就是打游戏!

上一篇:工厂方法模式

工厂方法模式:juejin.cn/post/708886…

入口

代码示例裢接:github.com/ruanch/Desi…

进入正题(手机和电脑都可以操作英雄、防御塔、小兵

现在平台越来越多,PC、手机、手表等等都可以运行同一款游戏,
那么如果在起初没有考虑到扩展是不是这些只能运行在一个平台。
如何在不动原来逻辑下,增加一个新的平台。抽象工厂就是干这个的。
首先把不同的平台抽象成一个抽象工厂类,里面存放创建角色、防御塔、小兵方法。
//抽象工厂

@objc protocol NEAbstractFactory {

    @objc optional func createRole() -> NEOperationRole

    @objc optional func createXiaoBin() -> NEOperationXiaoBin

    @objc optional func createTower() -> NEOperationTower

}
***接下来手机和PC去实现这个工厂***
class NEMobileFactory: NEAbstractFactory {

    func createRole() -> NEOperationRole {

        return NEMobileOperationRole()

    }

    func createXiaoBin() -> NEOperationXiaoBin {

        return NEMobileOperationXiaoBin()

    }

    func createTower() -> NEOperationTower {

        return NEMobileOperationTower()

    }

}
class NEPCFactory: NEAbstractFactory {

    func createRole() -> NEOperationRole {

        return NEPCOperationRole()

    }

    func createXiaoBin() -> NEOperationXiaoBin {

        return NEPCOperationXiaoBin()

    }

    func createTower() -> NEOperationTower {

        return NEPCOperationTower()

    }

}
***接下来每个平台都尊循创建协议,那么返回什么好?答案是实体类的操作, 所以抽象出来操作协议,
这个应该是平台核心的一个接口,只要按照这一套接口可以转换成一个新平台。***
@objc protocol NEOperationRole {

  @objc optional  func addRole(role:NERole_AF)

  @objc optional  func getRole() -> NERole_AF

}
***那么不同平台实现不同操作方式***
class NEMobileOperationRole: NEOperationRole {

    func addRole(role: NERole_AF) {

        print("在{手机}上面添加一个的《角色》对象")

    }

    func getRole() -> NERole_AF{

        print("在{手机}上面获取一个的《角色》对象")

        return NERole_AF()

    }

}
class NEPCOperationRole: NEOperationRole {

    func addRole(role: NERole_AF) {

        print("在{电脑}上面添加一个的《角色》对象")

    }

    func getRole() -> NERole_AF{

        print("在{电脑}上面获取一个的《角色》对象")

        return NERole_AF()

    }

}
***防御塔操作类和小兵操作类,类似代码***
***.......***
***接下来就是平台模型,也就是操作的对象***
//电脑工厂
let pcFactory:NEAbstractFactory = NEPCFactory()

//手机工厂

let mobileFactory:NEAbstractFactory = NEMobileFactory()

print("//======================角色=========================")

//造出操作角色对象

let pcOperationRole: NEOperationRole = pcFactory.createRole!()

//操作对象对角色进行操作

    //添加一个角色

let role = NERole_AF()

pcOperationRole.addRole!(role: role)

    //获取一个角色

let newRole = pcOperationRole.getRole!()

newRole.name = "电脑上的任意角色名称"

newRole.healthPoint = 100.0

newRole.magicPoint = 80.0

newRole.price = 18888.0

print(newRole.getRoleInfo())

//造出操作角色对象

let mobileOperationRole: NEOperationRole = mobileFactory.createRole!()

//操作对象对角色进行操作

//添加一个角色

let role1 = NERole_AF()

mobileOperationRole.addRole!(role: role1)

//获取一个角色

let newRole1 = mobileOperationRole.getRole!()

newRole1.name = "手机上的任意角色名称"

newRole1.healthPoint = 100.0

newRole1.magicPoint = 80.0

newRole1.price = 18888.0

print(newRole.getRoleInfo())

print("//======================小兵=========================")

//电脑造出操作小兵对象

let pcOperationXiaoBin: NEOperationXiaoBin = pcFactory.createXiaoBin!()

//操作对象对角色进行操作

//添加一个小兵

let xiaoBin = NEXiaoBin_AF()

pcOperationXiaoBin .addXiaoBin!(xiaoBin: xiaoBin)

//获取一个小兵

let newXiaoBin = pcOperationXiaoBin.getXiaoBin!()

newXiaoBin.name = "电脑上的步兵、弓箭手、炮兵"

newXiaoBin.healthPoint = 100.0

newXiaoBin.magicPoint = 80.0

print(newXiaoBin.getXaioBinInfo())

//手机造出操作小兵对象

let mobileOperationXiaoBin: NEOperationXiaoBin = mobileFactory.createXiaoBin!()

//操作对象对小兵进行操作

//添加一个小兵

let xiaoBin1 = NEXiaoBin_AF()

mobileOperationXiaoBin .addXiaoBin!(xiaoBin: xiaoBin1)

//获取一个小兵

let newXiaoBin1 = mobileOperationXiaoBin.getXiaoBin!()

newXiaoBin1.name = "手机上的任意角色名称"

newXiaoBin1.healthPoint = 100.0

newXiaoBin1.magicPoint = 80.0

print(newXiaoBin.getXaioBinInfo())

print("//======================塔=========================")

//电脑造出操作塔对象

let pcOperationTower: NEOperationTower = pcFactory.createTower!()

//操作对象对塔进行操作

//添加一个塔

let tower = NETower_AF()

pcOperationTower .addTower!(tower: tower)

//获取一个塔

let newtower = pcOperationTower.getTower!()

newtower.name = "电脑上的塔"

newtower.healthPoint = 100.0

newtower.defenseValue = 999.0

print(newtower.getTowerInfo())

//手机造出操作塔对象

let mobileOperationTower: NEOperationTower = mobileFactory.createTower!()

//操作对象对塔进行操作

//添加一个塔

let tower1 = NETower_AF()

mobileOperationTower .addTower!(tower: tower1)

//获取一个小兵

let newTower1 = mobileOperationTower.getTower!()

newTower1.name = "手机上的塔"

newTower1.healthPoint = 100.0

newTower1.defenseValue = 9999.0

print(newTower1.getTowerInfo())

输出信息:

//======================角色=========================

在{电脑}上面添加一个的《角色》对象

在{电脑}上面获取一个的《角色》对象

角色名称:电脑上的任意角色名称 ==> 血量: 100.0 魔法量:80.0 购买价格:18888.0

在{手机}上面添加一个的《角色》对象

在{手机}上面获取一个的《角色》对象

角色名称:电脑上的任意角色名称 ==> 血量: 100.0 魔法量:80.0 购买价格:18888.0//======================小兵=========================

在{电脑}上面添加一个的《小兵》对象

在{电脑}上面获取一个的《小兵》对象

小兵名称:电脑上的步兵、弓箭手、炮兵 ==> 血量: 100.0 魔法量:80.0

在{手机}上面添加一个的《小兵》对象

在{手机}上面获取一个的《小兵》对象

小兵名称:电脑上的步兵、弓箭手、炮兵 ==> 血量: 100.0 魔法量:80.0//======================塔=========================

在{电脑}上面添加一个的《塔》对象

在{电脑}上面获取一个的《塔》对象

塔名称:电脑上的塔 ==> 血量: 100.0 防御值:999.0

在{手机}上面添加一个的《塔》对象

在{手机}上面获取一个的《塔》对象

塔名称:手机上的塔 ==> 血量: 100.0 防御值:9999.0

总结

***工厂方法VS抽象工厂***
***可以对比下如果这个场景利工厂方法去实现会出现什么问题?答案就是你会发现很多地方需不断创建是手机平台实例还是PC平台实例。所以说:
***如果商品和商品操作类只有一种的情况下,利用工厂方法很方便的实现。***
***如果出现多种商品和多种操作类的时候,这时候就必须再次抽象出去,以达到方便扩展(开放-封闭原则)***

image.png