应用程序该如何拥抱变化

简介:
拥抱变化是极限编程非常重要的一个理念,OOP原则中的OCP原则(Open Close Principle,开放原则)也是拥抱变化的体现。不过,在写程序过程中,我们总是会遇到各种各样的变化,我们也尝过了“变化”的各种苦头,甚至都厌倦了再去迎接任何的变化,这并不是因为原则错误,而是我们一开始就没有准备好“变化”。这个文章对“拥抱变化”不再累述,我们直接来看一个使用面向服务架构的应用程序,体会一下拥抱变化。

 

我先说一下这个实例的内容,它非常的常见,就是设计一个权限控制服务,基本在我们的每一个业务系统中存在。不过,我有必要描述一下这个实例的背景,从而展现出为什么我需要做好变化的准备。目前我们有一个“插件工厂”,在这个插件工厂里面,我们希望向软件开发人员提供免费的界面插件、服务插件和业务插件,这样开发人员可以使用现有的插件来轻松/高效的构建自己需要的应用系统。换句话说,插件工厂的目标就是使用大众的力量帮助我们构建积木块的应用程序,插件工厂本身是一个最大的积木块仓库。

 

在插件工厂中,服务插件包括最基本的权限控制服务。这个权限控制服务向开发者提供非常简单易用的权限控制服务,并且开发者可以选择不同的权限控制服务提供商来构建自己的应用系统。打个比方,如果开发者构建的应用系统非常简单,他可以从插件工厂下载权限服务插件和一个“基于用户—权限的”权限控制服务提供商,它允许直接对用户授权;如果开发者构建的应用系统比较复杂,那么他可以下载权限服务插件和一个“基于角色的访问控制”权限控制服务;用户还可以利用现有的MemberShip实现自定义的权限控制服务。也就是说,开发者可以根据需要获取权限服务及相应的服务提供商来满足需求。经过思考,我在白板上画出了这个服务的实现原型。

 

在这个原型上,“Business Addin”即业务插件,是开发者需要设计的业务模块,这个业务模块将使用权限控制服务来实现权限的控制;权限服务分为契约和不同的提供商两部分,服务提供商对于业务插件来说是透明的,这些服务提供商可能是:(1)简单的权限控制服务提供商;(2)基于MemberShip的权限控制服务提供商;(3)基于角色的访问控制权限服务提供商;(4)其它服务提供商。不管开发者从插件工厂获得了哪个服务提供商,他都能够使用一致的模型来使用权限控制服务,并且这些权限控制服务能够与.NET现有的安全机制兼容。“Business Addin”使用权限服务的场景如下,我们希望尽可能使权限控制服务与开发者无关并且简单可重用。 

 

 

 

 “Business Addin”业务插件使用一般场景如下:

(1)首先通过[assembly: AddinPermission(“PermissionId”, “Name”)]来定义这个业务插件中需要检查的权限;
(2)然后在需要做权限检查的代码中调用权限服务的Demand方法实现检查。
复制代码
if (PermissionService.Demand(“PermissonId”))
{
    
//  当前用户拥有Id为“PermissionId”的权限,因此允许执行以下操作
}
else
{
    
//  向用户提示,您没有此操作的权限,请联系管理员给予分配“PermissionName”权限
}
复制代码
 

这样对于开发者的好处是显而易见的:(1)开发者也开发业务系统过程中不再需要设计任何的用户-角色-权限管理的应用模块;(2)开发者可以根据需要任意定义/扩展业务插件所需的权限,这些权限的管理最终由插件工厂里的权限服务提供商来实现。

那下面我们来看一下怎么来设计这个能够拥抱各种变化的权限服务。这个设计方案如下:
(1) 业务插件通过AddinPermission特性来定义一个权限,定义的权限会注册到权限服务的注册表中;
(2) 当业务插件请求一个权限时,它调用IPermissionService.Demand(“PermissionId”)来判断当前用户是否拥有该权限;
(3) 业务插件不依赖于权限服务提供商;
(4) 权限服务提供商在实现权限服务时使用权限服务的权限注册表来获取业务插件注册的权限实例,然后调用该实例来检查权限;
(5) 权限服务提供商默认权限的权限检查依赖于权限服务当前的用户/角色信息,然后对当前用户信息是否拥有该权限做出判断;
(6) 权限服务基于.NET的安全标识、实体、权限来设计,能够兼容.NET的安全机制。

 下面我们看一下相关的项目及服务定义。

 

运行效果图如下。在这里,我们为应用系统安装了SimplePermissionService,那么IPermissionService的提供商就是SimplePermissionService。如果用户需要其它的实现,比如ASP.NET MemberShipe实现的权限控制,就可以下载相应的插件来提供权限服务,但这对业务插件来说是透明的,它不需要做任何的代码变更。 


 权限服务定义如下。

复制代码
namespace  PermissionService
{
    
///   <summary>
    
///  权限服务契约,需要兼容.NET安全机制,即兼容IIdentity/IPrincipal/IPermission模型。
    
///   </summary>
     public   interface  IPermissionService
    {
        
///   <summary>
        
///  默认权限类型。如果用户使用AddinPermission没有指定权限类型,则使用该权限。
        
///   </summary>
        Type DefaultPermissionType {  get ; }
        
///   <summary>
        
///  当前安全实体。由用户标识和角色集合组成。
        
///   </summary>
        IPrincipal User {  get set ; }
        
///   <summary>
        
///  创建默认的权限实例。
        
///   </summary>
        
///   <returns> 每次返回一个新的权限实例。 </returns>
        IPermission CreateDefaultPermission();
        
// 判断当前用户是否拥有指定的权限。
         bool  Demand( string  permissionId);
         bool  Demand( string  addinId,  string  permissionId);
         bool  Demand(Addin addin,  string  permissionId);
         bool  Demand(RuntimeAddin addin,  string  permissionId);
    }

复制代码
在业务插件中使用权限服务,这里它没有对实际的权限服务提供商产生任何的依赖,只是通过SOA中的服务注册表来绑定一个IPermissionService服务,然后使用它来验证权限。
(1)权限定义
[assembly: AddinPermission( " MyPermissionId " " My Permission " )]
[assembly: AddinPermission(
" Guest " " Guest Permission " typeof (CustomizedPermission))]

(2)获取权限服务并请求验证权限 

复制代码
IPermissionService permissionService  =  
    Context.GetFirstOrDefaultService
< IPermissionService > ();
if  (permissionService  !=   null )
{
    
if  (permissionService.Demand( " MyPermissionId " ))
    {
        Response.Write(
" Permission demanded successfully. <br /> " );
    }
    
else
    {
        Response.Write(
" Permission demanded failed. <br /> " );
    }
}
else
{
    Response.Write(
" Please install a Permission Service Provider first. " );

复制代码

 

这个拥抱变化的思想是基于面向服务架构思想来实现的,在这里,“服务=契约 + 实现,契约=面向对象中的接口,实现=实现接口的类型”。业务插件依赖的是服务的契约,并不依赖服务的实现,服务的实现针对契约的不同提供商。我们可以根据应用系统的需要,在不更改业务插件的情况下,变更服务提供商来满足实际系统的需求。

 

关于权限服务提供商的实现会稍微复杂一点点,一个典型的提供商一般包括:(1)相关实体管理界面,如用户/部分/角色/权限分配;(2)权限服务实现。以下是一个典型的权限管理界面了。


在这里,权限服务提供商实现时,一般需要实现:(1)定义一个默认的权限;(2)实现IPermissionService;(3)在登录时设置IPermissionService.User。

 

 

示例服务的实现如下。

复制代码
namespace  SimplePermissionService
{
    [Service(
typeof (IPermissionService))] 
// 注册为IPermissionService服务契约的实现。
    
public   class  WebPermissionService : IPermissionService
    {
        
public  Type DefaultPermissionType
        {
            
get  {  return   typeof (DefaultPermission); }
        }

        
public  IPermission CreateDefaultPermission()
        {
            
return   new  DefaultPermission();
        }

        
public  IPrincipal User  
// 绑定HttpContext.User安全主体。
        {
            
get
            {
                
if (HttpContext.Current  !=   null )
                {
                    
return  HttpContext.Current.User;
                }
                
return   null ;
            }
            
set
            {
                
if (HttpContext.Current  !=   null )
                {
                    HttpContext.Current.User 
=  value;
                }
            }
        }

        
// 判断当前用户是否拥有指定权限。其它重载方法省略。
        
public   bool  Demand(
string   addin,  string  permissionId)
        {
            IPermission permission 
=  PermissionRegistry.GetPermission(
                addin, permissionId);
            
if  (permission  !=   null )
            {
                
try
                {
                    permission.Demand();
                    
return   true ;
                }
                
catch
                {
                    
//  todo: Log here.
                }
            }
            
return   false ;
        }

        // 其它重载方法...... 

    }

复制代码

目录
相关文章
|
3天前
拥抱变化:我的技术适应之旅
【5月更文挑战第3天】 在技术的瞬息万变中,我领悟了成长与适应的真谛。本文以第一人称的视角,讲述了个人如何在技术领域不断学习和进步,以适应不断变化的环境。从早期的困惑和挑战,到后来的主动学习和实践,文章描绘了一个技术人员自我提升的旅程。
17 4
|
12月前
|
架构师 数据管理 大数据
「应用架构」应用程序架构的当前趋势
「应用架构」应用程序架构的当前趋势
|
前端开发 JavaScript Java
总结自己使用技术的变化
根据自己的经验,总结自己使用技术的变化
117 0
|
数据挖掘 定位技术 调度
建立联系:协作应用程序在数字化转型中的作用
如今,越来越多的企业发现与遍布全球的员工保持联系变得越来越困难,采用协作工具变得越来越重要。尽管有许多协作工具可以做到这一点,但要使所有员工参与进来并朝着同一个方向发展,需要计划和毅力。
103 0
|
Kubernetes Cloud Native Devops
探索云计算对应用程序开发的影响
云计算如今改变了企业构建和运行应用程序的方式。人们需要探索发生这种情况的原因,并了解采用云计算的企业对其发展的期望。
166 0
|
监控 安全 API
云计算对应用程序和架构设计的安全影响
应用安全包含了一个非常复杂和庞大的知识体系:从早期设计和威胁建模去维护 和防护生产应用程序。随着应用程序开发实践的不断进步和采用新的流程、模式和技术,应用安全也在以难以置信的速度发展。云计算是这些进步的最大驱动因素之一, 它会产生相应的压力,使应用安全的状态发生变化,以确保这种进展尽可能安全地继续下去。本篇文章旨为希望在云计算环境中安全的构建和部署应用程序,特别是 PaaS 和 IaaS 的软件开发团队而提出的有助于减少常见安全问题若干建议
874 0
|
人工智能 前端开发 JavaScript
未来10年前端开源领域技术会有哪些变化?
2020年开启了下一个10年,站在这个起点展望前端的未来,必会面临巨大的变化和挑战。
637 0
未来10年前端开源领域技术会有哪些变化?
|
存储 数据库 云计算
云计算的可伸缩性迫使App服务无状态化,互联网营销
  场景内容   云计算因其软件上的按需付费模式而大获成功,它创造了一种伸缩性模型: 如果有两个公司,它们正好在相反的时区里,白天都需要10台服务器,晚上减少到1台。那么一个云计算服务商需要11台服务器就能同时为这两个公司提供服务——在任何一个时间点,拿出10台给一家公司用,1台给另一家。
977 0