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

你会发现我写随笔的特点就是喜欢单一,讲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传输给表现层。

另外服务器端与浏览器传输数据是使用ViewModel,它可以是直接使用ORM的model,也可以是DTO,当然,更复杂的情况是在View需要的数据模型与DTO或者数据库模型不匹配时将组织DTO或者Model根据View需要的属性建立一个ViewModel。

所以我们设计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=}, 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

表现层的设计(一)——常用的模式、Json与DTO的更多相关文章

  1. 表现层的设计(二)——MVC如何处理复杂的界面元素

    需求描述 一个比较复杂的页面,界面中包含的元素数据来自于许多个有关联或者无关联的表,然后我们要做的就是将数据呈现在界面上. 10年前大概都是这么干的 直接写一个复杂的SQL语句,返回一个包含所需数据的 ...

  2. 常用的模式、JSON与DTO

    表现层的设计(一)——常用的模式.JSON与DTO 上几篇博文介绍了 业务逻辑层和数据访问层,我认为写博文的作用主要是向业界的读者交流一种思想,点到为止,至于学习架构设计,通过几篇博文是讲不清楚的,还 ...

  3. 业务接口+UI层的设计(基于Castle实现的Repository)

    业务接口+UI层的设计(基于Castle实现的Repository) Repository层设计的文章见:[http://www.cnblogs.com/yomho/p/3297042.html]   ...

  4. 表现层(jsp)、持久层(类似dao)、业务层(逻辑层、service层)、模型(javabean)、控制层(action)

    转自:http://www.blogjava.net/jiabao/archive/2007/04/08/109189.html 为了实现web层(struts)和持久层(Hibernate)之间的松 ...

  5. 一个项目中说系统分为表现层、控制层、逻辑层、DAO层和最终数据库五层架构-转

    表现层就是看到的东西,比如你现在看到的当前页面控制层就将你的请求从页面传到后台代码逻辑层就是处理你的请求的代码DAO层就是将数据存到数据库中的代码数据库就是数据库了,存东西用的 ,DAO层就是将访问数 ...

  6. 使用View Model从表现层分离领域模型

    本文来自:http://www.cnblogs.com/shanyou/archive/2010/04/03/1703501.html Model-View-Controller(模型-视图-控制器, ...

  7. Web表现层

    目录 Web表现层调用过程... 2 延迟... 3 什么是延迟... 3 延迟的构成... 3 最基本的优化思路:... 4 Web表现层性能优化... 4 Web性能的基本指标... 4 Web性 ...

  8. JavaEE中表现层、持久层、业务层的职责分析(转载)

    表现层.持久层.业务层 注:本文转载于:http://www.blogjava.net/jiabao/archive/2007/04/08/109189.html 为了实现web层(struts)和持 ...

  9. 【转载】 JAVA三层架构,持久层,业务层,表现层的理解

    JAVA三层架构,持久层,业务层,表现层的理解 转载:http://blog.csdn.net/ljf_study/article/details/64443653 SSH: Struts(表示层)+ ...

随机推荐

  1. Python学习笔记(迭代、模块扩展、GUI 、编码处理等)

    PythonIDLE中的编码处理 http://www.tuicool.com/articles/NbyEBr 原文标题:Python中实际上已经得到了正确的Unicode或某种编码的字符,但是看起来 ...

  2. 【AngularJS】—— 11 指令的交互

    前面基本了解了指令的相关内容: 1 如何自定义指令 2 指令的复用 本篇看一下指令之间如何交互.学习内容来自<慕课网 指令3> 背景介绍 这例子是视频中的例子,有一个动感超人,有三种能力, ...

  3. Windows疑难杂症之开机无法显示桌面。

    开机无法显示桌面可能有以下两种情况. 1.系统故障或病毒引起explorer.exe无法加载启动. 2.注册表故障造成默认的值不是explorer.exe.(可能是安装了某些软件造成此问题) 3,某开 ...

  4. iOS中assign,copy,retain之间的区别以及weak和strong的区别(面试)

    • copy: 用于希望保持一份传入值的拷贝,而不是值自身的情况,即把原来的对象完整的赋值到另外一地方,重新加载一内存区,一个地方变了不影响另一个地方的对象. • assign:  简单的直接赋值,相 ...

  5. 基于iSCSI的SQL Server 2012群集测试(三)--SQL Server 2012群集安装总结

    5.SQL Server 2012群集安装总结 5.1 群集与非群集的安装区别总结 SQL Server虚拟名称: 非群集环境下,本地服务器的名称就是SQL Server服务器名称:但在群集环境下,由 ...

  6. eclipse无法自动识别出svn项目

    因为重新安装了svn插件,重启后发现原来的svn项目无法自动识别出来,连Team->Share Project都没有,而本地用tortoiseSvn是可以正常操作的. 后来我把项目删除然后重新导 ...

  7. informatica通用命令方式启动workflow

    #传mapping参数时#调用执行workflow,-sv informatica服务,-d 域 -u 用户,-p 密码 -folder知识库下的workflow所在文件夹,-wait wf_test ...

  8. Hadoop 面试题 之Hive

    1.Hive 有哪些方式保存元数据,各有哪些特点. 15. Hive内部表和外部表的区别 23.hive底层与数据库交互原理Hive的Hql语句掌握情况? 36.使用Hive或自定义mr实现如下逻辑: ...

  9. ICloud没有密码怎么注销?

    忘了密码的用这方法就可以啦1.现在我说你做 . 先进入 iCloud 点击 某某账户(要删的账户)2.第二栏密码那里删除原来的再输入ios(任意密码)3.然后点完成 之后会出现错误.请点 好.然后左上 ...

  10. discuz个人空间主题列表 图片模式实现方法

    discuz X3空间主题列表 图片展现模式,discuz实现个人空间主题列表调用图片模式,discuz home图片列表 如果需要实现该呈现方式,我们需要首先了解discuz封面图片存储原理:dis ...