zoukankan      html  css  js  c++  java
  • 表现层的设计(一)——常用的模式、Json与DTO

    上几篇博文介绍了 业务逻辑层和数据访问层,我认为写博文的作用主要是向业界的读者交流一种思想,点到为止,至于学习架构设计,通过几篇博文是讲不清楚的,还需要【基础】扎实的情况下,【反复】研究【权威】的书籍。

    你会发现我写随笔的特点就是喜欢单一,讲NHibernate就绝不会把easyui参合进来,而这次要谈得json也不会和MVC有什么关系。

    而实战当中,你会发现我确实可以将他们分开,在需要的时候重新组合各种类库和框架来达到我的目的。

    表现层(Presentation Layer)

    它主要由两部分组成:

    1.界面UI

    2.表现层逻辑

    界面UI在.NET中包括的几种形式:WEB(ASP.NET)、WPF、WinForm、Mobile

    而表现层逻辑通常需要用后台代码做一些事情。

    理论上我们应该尽量解除两者之间的依赖,以便于UI更容易切换。

    关于表现层的一些误区

    1. 觉得拖控件比较低端

    事实上“拖控件”在微软系有个学名的,叫 快速应用程序开发(Rapid Application Development,RAD)。

    它一种战术,况且微软企业应用架构中的事务脚本模式配合ASP.NET WebForm的事件驱动简直天作之合。

    实际上在传统的ASP.NET WebForm中也可以使用MVP模式来做到分离关注点,高不高端,取决于写程序的人,而不在于用什么工具。

    就好像昔年兵器谱排名第三的小李飞刀,他的飞刀也只不过是大治的铁匠花了三个时辰打造而成的。

    2.关于json的误区

    很多人认为json只有在Web开发中有效,甚至认为Easyui+ASP.NET MVC3中间通过json传输数据是唯一的情况。

    而事实上我们可以用它作为跨平台的传输格式,WCF正是利用了这一点。

    所以对象序列化json的时候,可能ASP.NET MVC3并不是必须的。

    设计类库时应该避开对其他框架的依赖。

    3.MVC就是ASP.NET MVC x

    实际上MVC只是一个模式,而微软对它进行了改进,设计出了ASP.NET MVC框架。

    MVC也只不过是WEB应用程序才使用的一种模式。

    另外MVC还延伸出几种模式,分别是MVP模式、PM模式(MVVM)。

    表现层常用的模式

    1.web中

    使用传统的ASP.NET,可以适当使用MVP模式分离关注点;

    或者使用ASP.NET MVC框架;

    angularJs的MVC;

    Vue.js的MVVM;

    2.windows中

    使用winForm同样是适当使用MVP模式;

    使用WPF自带MVVM模式;

    json与DTO的想法

    关于DTO:DTO,数据传输对象。理论上在表示层得到数据时应该是DTO,在服务层已经将DataTable/ORM的实体转化成DTO。但实际上若每个实体都要转DTO这是一个很大的工作量,实际上可能直接使用ORM的Model传输给表现层。

    另外服务器端与浏览器传输数据的模型我们叫它ViewModel,当然它也可以是直接使用ORM的实体,也可以是DTO,当然,更复杂的情况是在View需要的数据模型与DTO或者数据库模型不匹配时将DTO或者Model根据View(界面)的需要组织成一个ViewModel。

    所以我们设计Json序列化类的时候需要考虑几个问题:

    1.我们要序列化对象可能是DTO,也可能是ORM的实体,而实体复杂的情况会出现循环依赖,延迟加载。直接用微软自带的序列化类库报错,而使用MVC框架内置的Json序列化工具无法支持非Web的程序。

    2.服务器向客户端传输数据时,为了减少网络开销,则不应该传输多余的数据。Json序列化时该如何排除不需要的属性?

    3.如果是老系统使用.NET,没有微软自带的Json序列化类库,使用第三方类库。

    给出简单的解决方案

    这里使用了Newtonsoft.Json,并对前人类库进行一些整理,忽略对象循环依赖,能够支持移除不需要的属性。

            [Test]
            public void XLH()
            {
                DictionaryRepository rep = new DictionaryRepository();
                Dictionary dic = rep.GetByCodeLazy("bianma1", "code1");
                string json = Util.Json.Json.Serializer(new { dic ,total=3}, new string[] { "Category" });
                Console.WriteLine(json);
            }
    
            [Test]
            public void FXLH()
            {
                string json="{"Index":1.0,"Description":"描述1","Id":"160954d1-5e73-4ac8-a426-197f5bd616f9","Name":"字段1","Code":"code1"}";
                Dictionary dc=Util.Json.Json.DeSerializer<Dictionary>(json, null);
            }
    序列化与反序列化

    下面两个类可以直接使用。

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Newtonsoft.Json;
    using System.IO;
    
    
    namespace Util.Json
    {
        public class Json
        {
            /// <summary>
            /// 序列化
            /// </summary>
            /// <param name="obj"></param>
            /// <param name="settings"></param>
            /// <returns></returns>
            public static string Serializer(object obj, JsonSerializerSettings settings)
            {
                JsonSerializer scriptSerializer = JsonSerializer.Create(settings);
                StringWriter sw = new StringWriter();
                scriptSerializer.Serialize(sw, obj);
                string str = sw.ToString();
                sw.Close();
                return str;
            }
    
            /// <summary>
            /// 序列化(忽略对象循环依赖,忽略空值)
            /// </summary>
            /// <param name="obj"></param>
            /// <returns></returns>
            public static string Serializer(object obj)
            {
                JsonSerializerSettings Settings = new JsonSerializerSettings
                {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                    NullValueHandling = NullValueHandling.Ignore,
                    DateTimeZoneHandling = DateTimeZoneHandling.Local
                };
                return Serializer(obj, Settings);
            }
    
            /// <summary>
            /// 序列化(忽略对象循环依赖,忽略空值,排除指定列)
            /// </summary>
            /// <param name="obj">序列化目标对象</param>
            /// <param name="lstExclude">要排除的属性名列表</param>
            /// <returns></returns>
            public static string Serializer(object obj,string[] lstExclude)
            {
                ExcludePropertiesContractResolver exclude = new ExcludePropertiesContractResolver(lstExclude);
    
                JsonSerializerSettings Settings = new JsonSerializerSettings
                {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                    NullValueHandling = NullValueHandling.Ignore,
                    DateTimeZoneHandling = DateTimeZoneHandling.Local,
                    ContractResolver = exclude
                };
                return Serializer(obj, Settings);
            }
    
            /// <summary>
            /// 反序列化
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="str"></param>
            /// <param name="Settings"></param>
            /// <returns></returns>
            public static T DeSerializer<T>(string str, JsonSerializerSettings Settings)
            {
                JsonSerializer scriptSerializer = JsonSerializer.Create(Settings);
                JsonTextReader sr = new JsonTextReader(new StringReader(str));
                T obj = scriptSerializer.Deserialize<T>(sr);
                sr.Close();
                return obj;
            }
    
        }
    }
    类库1
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Newtonsoft.Json.Serialization;
    using Newtonsoft.Json;
    
    namespace Util.Json
    {
        /// <summary>
        /// 重写创建属性列表函数,使之支持排除指定属性
        /// </summary>
        public class ExcludePropertiesContractResolver : DefaultContractResolver
        {
            string[] lstExclude;
    
            public ExcludePropertiesContractResolver(string[] excludedProperties)
            {
                lstExclude = excludedProperties;
            }
    
            protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
            {
    
                IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
    
                foreach (string item in lstExclude)
                {
                    JsonProperty temp = null;
                    foreach (JsonProperty jp in list)
                    {
                        if (jp.PropertyName == item)
                        {
                            temp = jp;
                        }
                    }
                    if (temp != null)
                    {
                        list.Remove(temp);
                    }
                }
                return list;
            }
        }
    }
    类库2
  • 相关阅读:
    不等式(一)-Markov与Chebyshev不等式
    决策树学习
    k-NN最近邻算法(k-nearest neighbors algorithm)
    梯度下降(Gradient Descent)数学原理分析与实例
    求解素数
    shell基础命令使用
    安装jenkins
    idea拉取git
    shell常用命令
    linux 安装jdk
  • 原文地址:https://www.cnblogs.com/13yan/p/3281778.html
Copyright © 2011-2022 走看看