【角色】—— 分离开代码和权限需求,即实现代码和权限需求的解耦。(转)...

今天突然来了一个灵感,记录一下。以前总觉得说不清楚,看看这种表达方式是否可以说清。

两个原则:依赖接口编程,不要依赖实现编程最小获知原则

面向对象最重要的是什么?抽象。那么在权限这方面我们要如何抽象呢?

%E8%A7%92%E8%89%B2%E8%A7%A3%E8%80%A6.gif

  

最小获知原则

角色本身就是一种抽象出来的东东,用他来做隔离是最好不过了。因为客户里面是没有“角色”这个东东的。客户有岗位、部门、个人或者是工作组,但是就是没有角色。不是有句话吗,“什么?你不知道,那就好办了”。引用一下就是“什么?你这里没有,那就好办了”。

我们可以把角色说成是“部门”、“岗位”、“个人”,也可以说成是“岗位+个人”等各种说法,反正你那里没有角色,那我就怎么解释都行。最终解释权在我这里,咋说咋有理。

写代码的时候不用考虑客户的具体的权限方面的需求,只需要按照角色的规则编写,实现功能即可。

实现用户的各种权限需求也不需要去修改代码,也不用因此而影响代码如何去设计。只需要按照角色的规则来设置各个角色,即可实现客户的各种需求。

依赖“接口”编程

接口是广义的,不仅局限于interface。

角色是一种抽象,同时也可以理解是一种协议、规范。写程序的时候按照这个规范来设置权限相关的部分。用户的权限方面的需求也归结成各种角色。

客户只需要和角色打交道,同理,代码也只需要和角色打交道。角色就好像一个“翻译”,把客户的权限方面的需求翻译成“角色”,把程序也翻译成角色。都是“角色”就好沟通了。

当然了角色的规则并不是那么好设计的,每个人都会有不同的理解,不同的设计方式。但是我觉得有一点应该能够得到大家的认同:角色是一种接口、规范,用他来隔离代码和客户的权限方面的需求

角色是最顶级的抽象,具体怎么设计呢?每个人都会有不同的理解了。这里我只说自然框架里面是如何设计的。

其实思路是很简单的——登记造册。就是切成小块灵活组合

各行各业的项目,各种各样的客户,千奇百怪的需求,看是纷繁,其实万变不离其中。在信息管理项目的范围内,可以分为如下几种功能:

1、功能节点:大模块、小模块,节点、菜单。

2、操作按钮:查看、添加、修改、导出等等。

3、各种页面:列表、表单、导出、报表、图表等。

4、字段:列表里的列、查询里的查询条件。

5、记录:自己添加的记录、本部门的记录、体育类的新闻等等。

目前只能想到这五种了。如果您觉得不够,欢迎补充。

把这些信息登记造册,记录到数据库里,给每一个元素分配一个编号,一个编号就代表一个基本元素,比如功能节点,下图。

【功能节点及编号】

%E5%8A%9F%E8%83%BD%E8%8A%82%E7%82%B9%E7%BC%96%E5%8F%B7.gif

(FunctionID表示功能节点编号,描述一个项目都有哪些功能。)

【操作按钮及编号】

%E6%8C%89%E9%92%AE%E7%BC%96%E5%8F%B7.gif

(ButtonID表示操作按钮的编号。一个节点里有哪些按钮。)

【字段信息及编号】

%E5%AD%97%E6%AE%B5%E7%BC%96%E5%8F%B7.gif

(ColumnID就是字段编号,FunctionID表示功能节点编号,这个视图表示“功能节点里的表单需要的字段”)

这样角色到节点,就变成了这个角色可以访问哪些编号,有这个编号就可以访问,没有这个编号就不能访问。就这么简单。

其他的也是类似的方法,给按钮编号,给字段编号,给数据的查询条件(即角色到记录)加编号。然后角色和这些编号关联起来,角色有编号就可以用,没有编号就不可以用。

这里只提到了功能节点、操作按钮等,并没有具体的需求。这就是一种抽象,就是一种规则。写代码的时候只需要考虑这些就可以了,不用去考虑客户的具体需求。客户是按照部门分权限,还是按照岗位去分配?管他那些呢?俺是写代码的,那些权限方面的需求管我p事?

而对于客户来说,只需要创建一个角色,规定这个角色可以访问哪些功能节点,可以访问哪些按钮,可以查看哪些字段就可以了。这些可以交给客户的角色管理员来设置,客户的角色爱怎么便就怎么便。只要不增加、修改功能,那么就不需要改程序。

可能您会觉得这么操作对于客户来说太麻烦了,但是呀,人是活的,完全可以写一个程序来维护呀。如果您用过我的Demo,或者看过视频,您就会知道,添加一个角色是很轻松的事情。

视频演示http://www.cnblogs.com/jyk/category/220555.html

【添加角色的页面】

%E6%B7%BB%E5%8A%A0%E8%A7%92%E8%89%B2.gif

您也许会觉得这么多的编号,验证起来一定很繁琐,而且这些编号都是没有意义的,如何识别?谁能记得住这些编号?

验证当然是很简单的,基本上不用再写代码了,也不用调用什么函数,因为就这么几种情况,完全可以把验证的功能放在基类里面,子类根本就不用考虑权限验证的事情。

编号也不是给程序员看的,程序员也基本看不到这些编号,也不用看这些编号。

Ps:

角色是什么?就是钥匙,项目的各种功能,各种元素都是带锁头的,想要使用就必须有钥匙。角色就是钥匙,准确的说,就是钥匙的集合。拥有了角色,就相当于拥有了一串钥匙,就可以去打开各个锁头使用功能。

而领取钥匙(角色),可以以个人的身份领取,每个人都有不同的钥匙;也可以按照部门领取,部门里的所有人都拥有相同的钥匙;还可以按照岗位,同一个岗位拥有同一套钥匙。

还可以组合的方式,一个人在拥有了“岗位”带来的钥匙的同时,还可以拥有自己的钥匙。这样就很灵活了。

自然框架正在改进中,要出一个“稳定版”,就是把基础结构、命名空间、类名、函数名等固定下来,然后就不会再改了。

当然功能还是会不断扩展的,只是基础部分就不会在做改动了,就是要努力做到向下兼容。

代码改好之后就要出相关的文档、演示、视频等。争取一月底完成。

感谢大家的支持!

我希望对我的自然框架感兴趣的兄弟们可以点一下“推荐”,或者写一条留言。没有大家的支持,哪来的动力呀?

有些人总是觉得我的自然框架是没人要的,如果您认为自然框架还是有点用处的话,那么请您点一下“推荐”。谢谢!

没有其他的意思,只是想看看有多少人对我的自然框架感兴趣。

原文地址:http://www.cnblogs.com/jyk/archive/2010/01/14/1647266.html

转载于:https://www.cnblogs.com/n666/archive/2010/04/15/2190933.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
发布订阅模式是一种常用的设计模式,它允许我们定义对象间的一种一对多的依赖关系,当对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。发布订阅模式的核心在于发布者和订阅者之间的,发布者不需要知道订阅者的存在,订阅者也不需要知道发布者的存在,它们只需要知道消息的名称或者类型即可。 以下是发布订阅模式的核心实现代码: ``` class EventEmitter { constructor() { this.events = {}; } on(eventName, listener) { if (!this.events[eventName]) { this.events[eventName] = []; } this.events[eventName].push(listener); } emit(eventName, ...args) { if (this.events[eventName]) { this.events[eventName].forEach(listener => listener.apply(null, args)); } } off(eventName, listener) { if (this.events[eventName]) { this.events[eventName] = this.events[eventName].filter(l => l !== listener); } } once(eventName, listener) { const onceListener = (...args) => { this.off(eventName, onceListener); listener.apply(null, args); }; this.on(eventName, onceListener); } } ``` 以上代码实现了一个简单的EventEmitter类,它包含了四个方法:on、emit、off和once。其中,on方法用于订阅事件,emit方法用于发布事件,off方法用于取消订阅事件,once方法用于订阅一次性事件。 使用示例: ``` const eventEmitter = new EventEmitter(); // 订阅事件 eventEmitter.on('click', e => console.log(`clicked: ${e}`)); eventEmitter.on('hover', e => console.log(`hovered: ${e}`)); // 发布事件 eventEmitter.emit('click', 'button'); eventEmitter.emit('hover', 'link'); // 取消订阅事件 const clickHandler = e => console.log(`clicked: ${e}`); eventEmitter.on('click', clickHandler); eventEmitter.off('click', clickHandler); // 订阅一次性事件 eventEmitter.once('load', () => console.log('loaded')); eventEmitter.emit('load'); eventEmitter.emit('load'); // 不会触发事件 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值