• 平台化项目多语言架构


    平台化项目多语言架构实现

     

    项目为什么要平台化

    一、易维护

    封装可以大大的减少耦合,当发生变更的时候只需要修改一处地方。平台化项目和封装是有区别的,平台化项目是将项目所有组件、事件等制定一个标准,将这些组件基于标准进行高度封装,实现配置界面,通过配置大大的减少编码量。

    当需要整体变更的时候只需要更改这个标准便可,维护点更加的明确。

    二、可扩展

    1、首先有一点我要纠正,好多人都说封装性太强的东西只能做一些定性的项目,不能满足复杂的需求。这个观点是错误的,只能说你在使用别人高度封装的框架,而没有自已的框架 或者 没有掌握别人的框架 在或者 那个框架太LOW了。优秀的框架都是可以满足开发需求的,因为他们都留有很多自定义的地方。

    2、当项目需求不能满足的时候,可以按照标准去扩展现有组件或者创建新的组件。

    3、即使组件代码太垃圾也没关系,只要保证调用处是规范的,以后随时都可以对组件进行重构。

    三、成长性

    随着项目越来越多,标准会越来越完善,组件也会越来越多 

    多语言传统实现方式

    抛开数据库部分

    一、资源文件

    通过Cookie的值来决定到底调用哪个资源文件,我用的是.NET,我就来吐嘈下.NET资源文件的多么不方便

    1、需要定义N多的Key。

    2、为什么要把中文和英文分成两个文件,来回切换有多麻烦,而实际上我们需要的是这样的资源文件。

    3、性能差笨重

    二、XML

    1、需要自已设计代码

    2、无法在静态文件中使用,做不到前后分离

    3、查看不方便,没有EXCEL直观

    三、多个页面

     使用多个页面来实现多语言有两个缺点:

    1、当一个页面HTML结构发现变动的时候其它页面也需要变更

    2、没有现成的文件给专门的部门去翻译,要自已整理或者翻译者就在程序员身边

    基于平台化的实现方式

    一、设计资源文件

    如下图我们选择了EXCEL作为资源文件,根据功能的不同把EXCEL划分为多个文件,和传统的资源文件划分方式是不同的。

     

    根据页面定义了多个Sheet,有几种语言就定义几列,而不是有几种言语就定义多少文件和传统方式是质变。

    只要找个小弟把CN整理好,就不需要我们开发部门出任何体力了,也许会有人问为什么没有key,对!我们就是不需要用到key这个累赘,下面会讲到如何实现。

    二、如何解析EXCEL

    .NET可以使用Aspose.cell或者NOPI等组件把将EXCEL转为对象,可以将这个对象存进Cache减少IO操作

    存储的结构为List<T>

    public class T{

    目录

    模块

    页面

    语言A

    语言B

    语言C ...

    }

    这种结构可以很容易的筛选出当前页面所需要的语言

    三、实现1:模版解析引擎里面作手脚实现全局替换

    拿.NET MVC来举例子:

    使用RazorEngine.dll自已实现CSHTML转HTML

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public ActionResult Index(){
     
    string templateObj = GetViewByFilePath("~/Home/index.cshtml"); 
     
    var model=new { id = xxx };
     
    string html = Razor.Parse(templateObj ,model );
     
    //根据Excel转成的List<T>,筛选出当前页面的语言List<T>,对这个html 进行遍历替换处理
    //代码并无封装可言,我只是为了让大家看的更明白些
    foreach(var it in List<T>){
      html=html.Replace(it.默认语言,it.当前语言);
    }
     
    return View((new HtmlString(html),"~/Home/Shared/Language.cshtml");
    }

      

    //所有页面最后都使用Language.CSHTML文件  

    1
    2
    3
    4
    @model HtmlString
     
     
    @Model

    上面的替换代码只是最简单的例子更细节的地方我会在下面讲到  

    缺点: 

    即使使用了缓存也会有点点性能影响,至少不会比资源文件差。

    四、实现2:生成静态文件方式

    只需要开发默认语言的所有页面,然后通过工具的方式去生成其他页面

    如图: index_en.cshtml是通过工具生成出来的页面

    重写视图引擎根据Cookie自动调用相应的View文件

    复制代码
    {
        /// <summary>
        /// 自定义MVC视图引擎
        /// </summary>
        public sealed class BestViewEngine : RazorViewEngine
        {
     
            public BestViewEngine()
            {
            }
            /// <summary>
            /// 重写FindView
            /// </summary>
            /// <param name="controllerContext"></param>
            /// <param name="viewName"></param>
            /// <param name="masterName"></param>
            /// <param name="useCache"></param>
            /// <returns></returns>
            public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
            {
                var key ="languageKey";//COOKIE KEY
                var cm = CookiesManager<string>.GetInstance();
                if (cm.ContainsKey(key))//验证多语言COOKIE是否有值
                {
                    var cacheVal = cm[key]; //获取多语言后缀 (例如: en)
                    if (cacheVal.IsValuable())
                        viewName += "_{0}".ToFormat(cm[key]);//将原视图名添加后缀   比如 index 添加后缀之后就是 index_en
                }
                return base.FindView(controllerContext, viewName, masterName, useCache);//参数处理后调用BASE的FindView方法
            }
     
        }
    }
    复制代码

    工具的逻辑很简单  读取文件index.cshtml HTML =》获取语言List<T>=>筛选语言List<T>=>遍历替换成新的HTML 写入Index_en.cshtml 

    缺点

     使用的是工具,总感觉少了点什么。

    五、实现3:我们平台的实现方式

    1、页面所有的菜单是通过平台配置生成的

    通过后台配置生成出来的导航地图

    2、将多语言工具集成到平台配置界面,点击生成自动创建相应的VIEW文件

    生成后的目录

    3、数据库因为有 语言表和菜单表,Excel里面的Sheet就更容易筛选了,只要在列里面添加一个菜单ID便可,算法也更加精简,EXCEL的结构也支持更多花样

    六、替换的小技巧

    1、JS代码中文的提取

    JS使用页面的定义

    2、根据上图整理出来的Sheet,把JS部分和页面部分的中文都整理进去了,并且把当前菜单ID也加进去了方便筛选

    3、拿EXCEL里面的第一行和第二行来说吧,如果就这么单纯的替换会出现问题

    页面里面的【必填数字】,会变成 【Required数字】

     

    (1)、我们可以通过先替换长的,在替换短的来解决这个问题

    (2)、先替换当前页面的在替换公共的

    (3)、按上面2种替换方式可以保证99%页面替换是正确定的了,针对特殊情况们可以 【^移动】通过符号添加优先级  只要以^符号的开头的最先替换=》然后按长度=》按当前页和通用页,这样就能保证99.9%,以此类推(说白了就是在优先级上面做手脚)。

    您不给个赞吗?

     
    分类: 架构
  • 相关阅读:
    requireJS的优化工具 ---- r.js
    requireJS基本配置相关
    利用thread和sleep生成字符串的伪随机序列
    操作系统虚拟内存中的四种典型页替换算法(OPT,LRU,FIFO,Clock)
    考虑一个特殊的hash函数h,能将任一字符串hash成一个整数k……
    二叉树的遍历(C++非递归实现)
    判断一点是否在一条射线的左边
    如何判断单链表是否存在环
    移位数组的二分查找
    字符串相关函数的实现
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/5709317.html
Copyright © 2020-2023  润新知