表现层的设计(一)——常用的模式、JSON与DTO

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

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

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

表现层(Presentation Layer)

它主要由两部分组成:

1.界面UI

2.表现层逻辑

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

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

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

关于表现层的一些误区

1. 觉得拖控件比较低端

由于许多培训学校在解说JAVA和.NET的区别的时候,通常会讲一个能拖控件而一个不能,不能拖控件需要程序员自己写更加高端。

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

楼主从学生年代VB/Delphi/C++都是控件拖过来的,到现在也不会觉得它低端,它一种战术。

实际上在传统的ASP.NET中也可以使用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模式。

表现层常用的模式

1.web中

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

或者使用ASP.NET MVC框架;

2.windows中

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

使用WPF可以考虑MVVM模式;

3.移植的考虑

如果你希望你的winForm程序可以移植到Linux换成GTK的话,MVP模式也许是唯一的选择了。

json与DTO的想法

关于Json:ASP.NET MVC框架只能用于WEB应用程序,而json则可以更广泛地应用,所以json序列化的类库与框架的依赖并不是很好的设计。

在winform的项目中,这样的类库拿过来显然就编译不能通过了。

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

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

1.我们接受的要序列化对象可能是DTO,也可能是ORM的领域模型,而领域模型经常会出现循环依赖,延迟加载。直接用微软自带的序列化类库报错,而使用MVC框架来指定要序列化的属性那么如果不能使用MVC框架又该怎么办?

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);
}
序列化与反序列化

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

 类库1
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
 类库2
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
 
 
分类: 架构设计

常用的模式、JSON与DTO的更多相关文章

  1. 表现层的设计(一)——常用的模式、Json与DTO

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

  2. apache常用工作模式的区别

    apache常用工作模式有两种 worker模式1.线程模式2.占用资源少3.稳定性略差4.并发大 prefork模式1.进程模式2.占用资源多3.稳定4.并发一般  来自为知笔记(Wiz)

  3. Winform常用开发模式第一篇

    Winform常用开发模式第一篇 上一篇博客最后我提到“异步编程模型”(APM),之后本来打算整理一下这方面的材料然后总结一下写篇文章与诸位分享,后来在整理的过程中不断的延伸不断地扩展,发现完全偏离了 ...

  4. 泛型集合、datatable常用数据类型转换Json帮助类

    泛型集合.datatable常用数据类型转换Json帮助类 using System; using System.Data; using System.Configuration; using Sys ...

  5. python设计模式之常用创建模式总结(二)

    前言 设计模式的创建模式终极目标是如何使用最少量最少需要修改的代码,传递最少的参数,消耗系统最少的资源创建可用的类的实例对象. 系列文章 python设计模式之单例模式(一) python设计模式之常 ...

  6. python常用模块之json、pickle模块

    python常用模块之json.pickle模块 什么是序列化? 序列化就是把内存里的数据类型转换成字符,以便其能存储到硬盘或者通过网络进行传输,因为硬盘或网络传输时只接受bytes. 为什么要序列化 ...

  7. 2017.11.6 JavaWeb-----第七章 JavaWeb常用开发模式与案例

    JavaWeb-----第七章 JavaWeb常用开发模式与案例 (1)单纯的JSP页面开发模式 通过在JSP中的脚本标记,直接在JSP页面中实现各种功能.称为"单纯的JSP页面编程模式&q ...

  8. 正则表达式中常用的模式修正符有i、g、m、s、x、e详解

    正则表达式中常用的模式修正符有i.g.m.s.x.e等.它们之间可以组合搭配使用. 它们的作用如下: //修正符:i 不区分大小写的匹配; //如:"/abc/i"可以与abc或a ...

  9. 常用的package.json以及React相关

    常用的package.json以及React相关 前言 package.json 的简单介绍 简单版的 package.json 必备属性(name & version) name 字段 ve ...

随机推荐

  1. PHP-微信公众平台开发-接收用户输入消息类型并响应

    原文:PHP-微信公众平台开发-接收用户输入消息类型并响应 <?php // 该代码块用于接收用户消息,根据用户输入的消息类型进行判断,文本,图片,视频,位置,链接,语音等,并取得值,处理后给予 ...

  2. 用windows性能监视器监控sqlserver的常见指标

    用windows性能监视器监控sqlserver的常见指标   上边文章中提到win的性能监视器是监控数据库性能必备的工具,接下来我就给大家介绍一些常见的监控指标,其实无非就是磁盘,cpu,内存等硬件 ...

  3. 【Heritrix基础教程2】Heritrix基本介绍

    1.版本号说明 (1)最新的版本号:3.3.0 (2)最新release版本号:3.2.0 (3)重要历史版本号:1.14.4 3.1.0及之前的版本号:http://sourceforge.net/ ...

  4. 我的时间,GTD做主

    可能每一次总结的时候,我们都在努力的回顾,我这几天都干了什么,结果回顾半天得到的结果就是:我也不知道,仿佛什么都没有做似的.事实上不然,你已经做了好多事,但却始终有这样的感觉,有的时候都在自己发问:我 ...

  5. php操作xml并插入到数据库中

    php操作xml并插入到数据库中 <? php header('content-type:text/html;charset=utf-8'); mysql_connect('localhost' ...

  6. Hybrid

    “榕树下·那年”移动app ( hybrid ) 开发总结   榕树下网站本身的技术人员并不多,所以app开发的任务就到了母公司盛大文学这边.       盛大文学无线业务中心负责这次具体开发任务. ...

  7. [翻译]MEAN.IO与MEAN.JS的前世今生

    写在前面: 因为项目要求要学习mean,所以要从搭建环境开始,网上的教程不怎么多,但是感觉方法倒是不少,也没多想,就开始安装,运行起来发现怎么和安装教程中的目录结构不同? 想了好久,也翻看目录半天,总 ...

  8. APUE学习笔记(1):APUE运行环境

    APUE全称<Advanced Programming in the UNIX Environment>(UNIX环境高级编程) 书中例子大都使用作者自己写的头文件,所以需要解决一下,还好 ...

  9. lua及luci学习

    由于项目需要对Luci进行修改,所以这里开始地luci进行较深入的研究. 探索其中的运行路径. Openwrt默认的HTTP服务器为uhttpd,该WEB服务器是由Luci的开发者自行开发的,非常小巧 ...

  10. ACdream 1195 Sudoku Checker (暴力)

    Sudoku Checker Time Limit: 2000/1000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) Submi ...