-
Notifications
You must be signed in to change notification settings - Fork 435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
神杀核心架构设计 #212
Comments
首先开始对设计目标的讨论,即首先统一理想中的神杀架构,这部分讨论的附加原则:
|
架构设计宗旨(草案)
|
基本原则4,这条对于一个有经验的程序员来说,无论多麻烦的程序都没问题,对于没接触过编程的人来说,无论架构多简单,他们都认为在看天书。如果想让一个不懂c++的人上手就维护,无异于让他们一步登天。所以我认为无论特殊写法有还是没有,这条都是不可能的。 |
而且现状很残酷,“看不懂”“没时间”的人越来越多,这种人还都想一步登天,简直扯蛋。 |
如果汽车继承一个水果类(极端的例子),这种继承显然很难理解,我们要尽量规避这种很难理解的特殊写法。 |
4的意思是符合常人的思维,或者让这种设计思路容易理解。没有 @Fsu0413 说的意思 |
容易理解……要想程序容易理解,除非全部推重,这种类似打补丁的修正方式无异于给已经搭好的房子砌砖 |
到最后砖头到处都是,房子变成迷宫了 |
王垠有一段自称很厉害的代码,只有40行。 可能真的很厉害,世界上也一定存在能理解的人,但是确实很难理解,所以也没有哪里用上这段代码。 我觉得我们的代码应该把好理解作为原则之一。 |
所以我们从最基本的开始讨论我们设想的架构 现有框架全部不存在。 |
不过推重的工作量你懂的。啦啦你可以想象一下,为什么我在公司做的软件,都是为新机型开发,但是都是在旧机型已有代码的基础上改?因为走迷宫所需要的时间和精力远远小于拆了房子重建。 |
参考讨论基本原则的第三点。我们首先统一一下大家的目标,先有共同的目标,再针对现状做一些符合实际的调整。 不然A认为神杀应该窃取用户机密,B认为神杀有权利保护用户电脑的安全,他们也不知道对方的想法,然后A改的部分是为A的目的服务的,B改的部分是为B的目的服务的,到最后只会引发更大的改动量。 符合共同目标的话,工作量大的话就当是给以后的维护人员一个任务吧。 |
神杀的代码是我见过的最容易理解的项目的代码了,我可以透露下我们公司的代码结构,那个代码……一层接着一层的函数调用和消息打包发送,各种异步接口同步接口,分析代码真的就是在走迷宫,分析的稍微有点偏差,绝对再也回不来,只能从头开始重新走。那个代码从00年的base开始就一直用了,一直在搭好的房子里砌砖,那是个真·迷宫,啦啦没进过公司肯定不知道这现象。事实上大多数商品里程序的代码,比神杀的代码难理解的多,作为神杀开发者竟然认为神杀代码难理解,我真的无法想象这样的事。 |
最初的第一套base肯定要我们去写,推重的提出者是现在的mogara而不是未来的mogara。 |
美国宪法的序言只有一句话: |
如果宗旨只是让代码容易理解的话,那么大家现在就可以散伙。我这句话完全不开玩笑,因为我感觉现在这个程度的代码,只要有点基础的人应该都能看懂。啦啦是真没进过软件公司不知道维护公司代码的难度,还是空想可以让没有基础的人一步登天呢?? |
我睡觉了……明天再说,可能我说的话有点极端……各位见谅 |
我是想把这一条纳入宗旨的,但不是宗旨的全部呀。如果大家对神杀应该怎样有了普遍的共识,如果一个设计违背了大多数人的愿望,就可以用很小的成本否定这个设计了。从基本的愿望到设计的具体细节,一步步来,就可以高效有条理的敲定架构从宏观到具体的实现方法;而现状是对架构的设计至今都没有完整的方案。 |
而且宗旨另一个目的是为了避免今后违背宗旨。宗旨不是改革目标,不是改完就作废了。 |
不管怎么说0基础一步登天是完全不可能的。如果把它当作宗旨,那么为了这个虚无的宗旨的努力又有什么意义呢,反正也实现不了 |
你从哪里推断出我说的代码易于理解是“0基础也可以看懂代码”的呢? |
上面的回复啊…… |
哪一条? |
“我睡觉了”的下一条 |
这一条里除了“这一条”三个字指“代码易于理解”,其他我都是在说我们应该先把愿望统一。 |
不过现在我的感觉是这个愿望太虚无…… PS:睡不着了…… |
不行我必须睡了……明天还要上班 |
。。。睡吧 establish justice, insure domestic tranquility, provide for the common defense, promote the general welfare, and secure the blessings of liberty to ourselves and our posterity |
即在一个复杂不易理解的设计和一个易于理解的设计面前,我们共同期望那个易于理解的设计。 现在我们只谈共同期望。先明确一些期望,各位奆神才能更好的设计程序。才能进一步打破现在想改,但一直又没有方案的局面。 |
通宵对宗旨目前面临的各种疑问进行了补充,希望能更好理解。睡了。 |
描述相同的技能,在不同模式下结算有一些差别,不需要在技能里额外的代码体现这种差别。这是内核的任务。 |
如果把帷幕在新出的(可能是用户自定义模式)里改成不相干的效果,内核没有义务让相同的代码能在新模式正常工作。 |
所以在内核层面看,相同的技能指名字和效果均一致的技能。内核的目的是实现相同的技能在不同规则下有应有的效果。 |
=。=啦啦说的对 |
我投赞成票 |
我投赞成票←_←感觉其实虽然讨论很激烈但是共识还是有的 |
刚下课肥来0.0~ 一种代码的默契,“如果是我写我也会这样写”的认同感,大概就是宗旨的意图吧。 |
我是期望能达成开发新桌游的效果,这也就是独孤安河神所想的“管理资源,提供服务”的神杀。 |
吸收各方意见,并解答了一些疑问的开发宗旨修改完成了,宏观上的设计思想是“微内核”,即3.i 现在可以就一些具体的模块提出构想,当然总的开发宗旨也可以继续补充。 |
首先是三国杀模块中的内核。 内核的宗旨很明确了,即讨论在技能未知的情况下如何实现规则。 以下继续内核设计,如何在角色、技能、游戏牌等内核外因素未知的情况下实现内核。为什么要先敲定内核呢?因为各模块之间的关系往往是网状的,唯有三国杀模块与各模块关系是星状的,而三国杀模块中,内核之外的部分是在规则环境下编写的,所以与各职能模块产生联系的只是内核。敲定了内核设计之后,各模块必须实现哪些接口函数就一目了然了。 |
这是我为了敲定设计而第二次通宵,希望有想法的小朋友都能积极提出意见。毕竟我也有不熟悉的模块,这些部分我就算是一直不休息也没有能力主持相关的具体设计。 |
@takashiro 其实我不知道这个所谓“难理解的神杀代码”是什么,况且如果连我都认为(仅限于我维护的部分的)神杀代码难理解的话,我也就不用在软件公司呆着了。 |
@Fsu0413 那我们先以high cohesion and low coupling的原则重新设计一下程序,完成后比对一下这种结构和现有结构的差别再说,OK?而且有一点很明确,神杀是要继续3年5年10年的,没有新的架构的话,我们以后要始终对2010年就定型的架构添砖加瓦。 |
继续内核。 |
补充一下,我们的设想中三国杀模块是可拆卸的,并且架构成熟后,这个模块是有被拆卸的预期的,所以我们三国杀模块之内的部分不以"M"开头。同理,因为可拆卸,所以我们是可以作为第三方库被使用的,这时候就要避免和开发者本身设计的类重名,所以类统一用“M”开头。 |
根据三国杀模块可更换的预期,我们要根据第三方开发者水平等因素,规定低水平开发者不得调用一些危险的命令,所以在协议上有记录权限等级的必要(根据封装设计的原则,这里不讨论具体实现)。
|
根据面向对象的五个基本原则(SOLID)之首SRP:Single Responsibility Principle,在三国杀模块中的角色只需具有三国杀规则概念中角色的属性就够了,其他如何通信什么的问题都去死吧。这样就C/S结构中三国杀模块的角色分布就清晰了:Server和Client都会有三国杀概念中的角色(SanguoshaPlayer),这个角色的职能很小,只是记录游戏状态,所以无论是Server和Client都会用到它的全部状态,但是通信由网络模块承担。不仅是三国杀有角色呀,几乎每一款游戏都有角色,所以在内核中,要实现这个抽象基类及其协议:
|
具体到继承MAbstractPlayer的SanguoshaPlayer
|
为了保证各角色信息在C/S之间传输通畅,在内核内部要有通信协议(这份协议不负责玩家在线还是离线、用户名之类杀无关的传统Player属性的传输)。这份协议是封装在内部的,网络模块不知道具体情况,所以需要内核主动调用网络模块的API。
经历一个封包过程的好处是,两模块相对独立。网络模块能发送MAbstractLogicPacket,但其构成只有内核自己知道,也就是说无论内核怎么实现,网络模块都能在不知道派生类实现的情况下发送出去,同样是我们“高内聚,低耦合”的思路。
|
虽然用了UML绘图工具,但不完全是类图,所以线条和模块就很随意,不代表具体的关系,根据文字设计有具体含义。 上图中,有几个关键点很清晰。
|
内核和网络模块的协议基本靠上述关键点中的前三个建立了(先不考虑权限等级,以后可以在抽象包基类上再分各种等级的包)。 内核与UI的关系就有些复杂了,我们首先要理顺这个关系才能定制合适的协议,从而用抽象基类搭建架构。 |
UI 与内核关系相当密切,而且理想中换掉游戏模块,UI 也应焕然一新才对。 Q:内核直接指定了具体的UI,不是违反了“模块独立”吗? |
UI 对内核的协议应该开放手牌操作面板、选牌框、角色指示物等的具体样式,实现方式是把其中具体组件的位置、样式等信息任由内核修改。同时开放按钮、方块、圆等基础组件,供内核拼接组成新的高级组件。 看起来很复杂?其实现在的通信机制和这个区别并不大,明确网络模块不参与封包和协议之外的解包是游戏内核独立出来(i.e. 内核更换后,网络模块能不影响程序正常工作)的关键。 以上一例简单,一例复杂,一例组合了三种模块,用三种差异较大的情况分析了这种思路的实现,在设计其他模块之间的协作时,可以有个参照。 |
A指向B表示A为B提供服务,根据服务构建协议,虚线指通过网络模块提供服务。 |
AI模块属于内核,还是独立于游戏模块是个问题。考虑到一般卡牌游戏也存在敌友关系,以及威胁性等判断,暂时把AI作为独立的模块讨论,AI和内核S的协议可能不会太严格。 |
前几天和啦啦讨论之后决定ai作为客户端,与人类玩家地位相同 |
首先,登陆用例。
登录名或密码未输入或验证码->框高亮 启动时用户名一栏填上次登陆的用户名、下拉框显示记录的其他用户名、每一条旁边有个X,点击删除记录 注册账号->启动浏览器打开注册页面 |
讨论基本原则:
The text was updated successfully, but these errors were encountered: