前言

  自从此博客发表以及代码开源以来,得到了许多人的关注。也没许多吧,反正在我意料之外的。包括几位大牛帮我做订阅号推广,真的很感谢他们。另外,还有几个高手给我提了一些架构上的问题。其实本身这个项目是没有做什么架构设计的。只是简单分了分层。不过我在经过仔细思考之后决定对项目架构做些调整,当然在我的技术范围之内,我相信还会有第二次,第三次甚至更多重构,我希望把他变得更加完美。

重构思路

  对于重构思路,我首先想到的是,让程序能够支持多种数据库,比如我现在用的是SQLServer,而好多朋友用MySQL或者mongodb等其他数据库,本来初衷没有想这么多,认为此项目就是一个关于SignalR和LayIM的Demo实现。不过能优化一下是最好的。然后我就想到了一个经典的用法,那就是反射工厂。通过反射来动态生成对象,然后调用方法,而不用去改UI的代码。

  比如,当我同样写了一个MySQL的获取用户基础信息的方法,那么我就需要去改Controller中的代码:

  

     public JsonResult GetBaseList(int userid)
{
//SQLServer数据库调用方法
//var result = LayimUserBLL.Instance.GetChatRoomBaseInfo(userid);
//MySQL数据库调用方法
//var result = LayimUserBLL_MySQL.Instance.GetChatRoomBaseInfo(userid);
return Json(result, JsonRequestBehavior.AllowGet);
}

  这样的话要改动的地方太多了,其实重构也很花费时间,但是是值得的。于是我先在BLL层定义了方法接口。

  public interface IUser : ISearch
{ #region 获取用户登录聊天室后的基本信息
JsonResultModel GetChatRoomBaseInfo(int userid);
#endregion #region 获取群组人员信息
JsonResultModel GetGroupMembers(int groupid);
#endregion #region 用户登录或者注册流程
/// <summary>
/// 用户登陆或者注册,返回用户id如果为 0 说明密码错误
/// </summary>
/// <param name="loginName"></param>
/// <param name="loginPwd"></param>
/// <param name="nickName"></param>
/// <returns></returns>
int UserLoginOrRegister(string loginName, string loginPwd); #endregion #region 用户创建群
JsonResultModel CreateGroup(string groupName, string groupDesc, int userid);
#endregion #region 获取用户有关的消息
JsonResultModel GetUserApplyMessage(int userid);
#endregion #region 获取某个用户的好友列表
/// <summary>
/// 获取某个用户的好友列表
/// </summary>
/// <param name="userid">用户ID</param>
/// <returns>返回格式如下 ""或者 "10001,10002,10003"</returns>
string GetUserFriends(int userid);
#endregion #region 读取用户所在的群
string[] GetUserAllGroups(string userId);
#endregion }

  这样,我在把原本LayimBLL继承这个接口,然后相应的改一下代码。基本不用变,因为我定义这个接口的时候就是参照原类中的方法定义的。同样,在MySQL文件夹下同样新建一个类继承自这个接口,然后模拟一个MySQL的实现。

    public JsonResultModel GetChatRoomBaseInfo(int userid)
{
var result = new BaseListResult();
result.mine = new UserEntity
{
avatar = "/headphotos/default.jpg",
id = ,
sign = "我来自MySQL",
status = "online",
username = "MySQL"
};
return JsonResultHelper.CreateJson(result, true);
}

  那么反射工厂做了什么工作呢。通过读取配置文件来动态生成相应的对象实例。核心代码就在于Type.GetType方法,然后调用Activator.CreateInstance方法创建实例。

  public class LayIMFactory
{
#region 私有变量和方法
readonly string asemmblyPath = "LayIM.BLL.Classes.{0}.{1},LayIM.BLL";
private string InstanceName
{
get { return AppSettings.GetValue("DBType"); }
}
private string GetFullAsemmblyPath(string className)
{
return string.Format(asemmblyPath, InstanceName, className);
}
#endregion public IUser Create()
{
return Create<IUser>(BLLClasses.User);
} /// <summary>
/// 通过反射来获取某个类的实例
/// </summary>
/// <typeparam name="IT"></typeparam>
/// <param name="className"></param>
/// <returns></returns>
private IT Create<IT>(string className)
{
var nameSpace = GetFullAsemmblyPath(className);
Type t = Type.GetType(nameSpace);
IT instance = (IT)Activator.CreateInstance(t);
return instance;
}
}

  然后,Controller稍微改动一下。这样Controller只希望要一个实现IUser接口的实例对象,并不关系你内部用的是MySQL还是SQLServer,这样能够实现Controller和BLL层解耦的目的。

  

当然后边我做的工作很多,代码就不全粘了。下面运行一下,看看效果。

重构后的代码演示

  首先配置文件中的,DBType我们把值设为SQLServer.(图片中的数据是从sqlserver数据库中读取的)

  

  然后再将配置文件中的DBType的值改为MySQL(由于尚未开发和MySQL对接,为了模拟演示,数据为代码中写死的。见上文)

总结

  哦啦,虽然这个例子稍微有点简单,但是也比之前的代码好了一点,代码重构的过程是很痛苦的,你要推翻你以前写的好多代码,甚至整个项目都要重写。路还长,这个项目也是让我成长不少,继续加油。没有看过此系列的小伙伴可以移步这里哦:

  ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室 实战系列(不断更新中)

ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十一) 代码重构使用反射工厂解耦的更多相关文章

  1. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室 实战系列

    ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言  http://www.cnblogs.com/panzi/p/5742089.html ASP.NET S ...

  2. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十二) 代码重构使用反射工厂解耦(一)缓存切换

    前言 上一篇中,我们用了反射工厂来解除BLL和UI层耦合的问题.当然那是最简单的解决方法,再复杂一点的程序可能思路相同,但是在编程细节中需要考虑的就更多了,比如今天我在重构过程中遇到的问题.也是接下来 ...

  3. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言

    前端时间听一个技术朋友说 LayIM 2.0 发布了,听到这个消息抓紧去官网看了一下.(http://layim.layui.com/)哎呀呀,还要购买授权[大家支持一下哦],果断买了企业版,喜欢钻研 ...

  4. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取)

    大家好,本篇是接上一篇 ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言  ASP.NET SignalR WebIM系列第二篇.本篇会带领大家将 LayIM ...

  5. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(二) 之 ChatServer搭建,连接服务器,以及注意事项。

    上篇:ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取) 上一篇我们已经完成了初步界面的搭建工作,本篇将介绍IM的核心内容 ...

  6. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(三) 之 实现单聊,群聊,发送图片,文件。

    上篇讲解了如何搭建聊天服务器,以及客户端js怎么和layui的语法配合.服务器已经连接上了,那么聊天还会远吗? 进入正题,正如上一篇提到的我们用 Client.Group(groupId)的方法向客户 ...

  7. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(四) 之 用户搜索(Elasticsearch),加好友流程(1)。

    前面几篇基本已经实现了大部分即时通讯功能:聊天,群聊,发送文件,图片,消息.不过这些业务都是比较粗犷的.下面我们就把业务细化,之前用的是死数据,那我们就从加好友开始吧.加好友,首先你得知道你要加谁.L ...

  8. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(五) 之 加好友,加群流程,消息管理和即时消息提示的实现

    前言 前前一篇留了个小问题,在上一篇中忘了写了,就是关于LayIM已经封装好的上传文件或者图片的问题.对接好接口之后,如果上传速度慢,界面就会出现假死情况,虽然文件正在上传.于是我就简单做了个图标替代 ...

  9. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(六) 之 Layim源码改造右键菜单--好友、组管理功能的实现。

    前言 上一篇中讲解了加好友的流程,本篇将介绍好友管理,群组管理的右键菜单功能.当然由于菜单项目太多,都实现也得花费时间.只讲解一下我是如何从不知道怎么实现右键菜单到会自定义菜单的一个过程.另外呢,针对 ...

  10. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(七) 之 历史记录查询(时间,关键字,图片,文件),关键字高亮显示。

    前言 上一篇讲解了如何自定义右键菜单,都是前端的内容,本篇内容就一个:查询.聊天历史纪录查询,在之前介绍查找好友的那篇博客里已经提到过 Elasticsearch,今天它又要上场了.对于Elastic ...

随机推荐

  1. JavaScript基础知识汇总

    1. 图片热区: <img src="logo.jpg" usemap="#logo"> <map id="logo" n ...

  2. C/C++ http协议加载sessionID

    很多时候,使用一个既定的API虽然可以去完成一些任务,但是还是不如自己写来的那么随性和自由. http协议,最常用的get,post两种方式传输数据,关于post,有时候,需要用到加载cookie信息 ...

  3. ABAP之声母韵母

    我们一开始上学的时候,老师最先教的是什么? 拼音,声母,韵母,声调等等. 那么ABAP里什么是这些东西呢? 基础的数据类型,已经数据字典里的东西:域,数据元素,结构,视图,表,搜索帮助,锁... 数据 ...

  4. junit高级篇(参数化、打包测试)-实例代码

    工程目录: 参数化测试,SquareTest.java: import static org.junit.Assert.*; import java.util.Arrays; import java. ...

  5. Bootstrap自带的chart插件

    <!doctype html> <html> <head> <title>Line Chart</title> <script src ...

  6. dpkg命令的用法

    dpkg 是Debian package的简写,为”Debian“ 操作系统 专门开发的套件管理系统,用于软件的安装,更新和移除. 所有源自"Debian"的Linux的发行版都使 ...

  7. net中序列化读写xml

    参考http://www.cnblogs.com/fish-li/archive/2013/05/05/3061816.html 我们可以直接使用XmlTextReader.XmlDocument.X ...

  8. 为什么高手离不了Linux系统?这就是我的理由

    摘要: 通过本文来记录下我在Linux系统的学习经历,聊聊我为什么离不了Linuxx系统,同时也为那些想要尝试Linux而又有所顾忌的用户答疑解惑,下面将为你介绍我所喜欢的Linux系统,这里有一些你 ...

  9. java web图片上传和文件上传

    图片上传和文件上传本质上是一样的,图片本身也是文件.文件上传就是将图片上传到服务器,方式虽然有很多,但底层的实现都是文件的读写操作. 注意事项 1.form表单一定要写属性enctype=" ...

  10. goldengate 12c 12.2 新特性(updated)

    GoldenGate 12.2已经提供下载,增加了不少新特性 1. 异构配置加强不在需要sourceDefs和AssumeTargetDefs文件,在队列文件中已经包含metadata信息,比如tab ...