业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份
业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份
WinForm酒店管理软件--框架这篇随笔可以说是我写的最被大家争议的随笔,一度是支持和反对是一样的多。大家对我做的这个行业的前景有很大的建议啊。虽然市场有困难,但好技术架构肯定是前提。事实也是,当你还是一个孩子准备和一群成年人竞争时,你可以被人轻易的暴力推到,可以被人家多年的经验轻松完虐,别人也会说“大人说话小孩子一边玩去”。这些都是过程,作为一位有准备的小孩会有心理准备的,今天准备把之前的架构中的使用策略实现业务类接口在TCP,HTTP,BLL模式下的实例大家一起交流下。这样说大家可能比较模糊,
我提几个问题。
1、之前有人问我IBLL是干什么的?
例如:

- [ServiceContract]
- public interface IRadioListBLL
- {
- [OperationContract(IsOneWay = false)]
- List<RD_RADIO_LIST> Query();
- }

using System;
using Yike.Model.DataBase;
using System.Runtime.Serialization;
namespace Yike.Model.Radio
{
/// <summary>
/// 无线电清单
/// </summary>
[DataContract]
public class RD_RADIO_LIST
{
/// <summary>
///
/// </summary>
[DataMember]
[FieldProperty(PRIMARY_KEY = 1, COLUMN_TYPE = "NUMBER", COLUMN_LENGTH = 22)]
public long REDIO_UKID
{
get;
set;
}
/// <summary>
///
/// </summary>
[DataMember]
[FieldProperty(PRIMARY_KEY = 0, COLUMN_TYPE = "VARCHAR2", COLUMN_LENGTH = 20)]
public string REDIO_NAME
{
get;
set;
}
/// <summary>
///
/// </summary>
[DataMember]
[FieldProperty(PRIMARY_KEY = 0, COLUMN_TYPE = "VARCHAR2", COLUMN_LENGTH = 100)]
public string URL
{
get;
set;
}
/// <summary>
///
/// </summary>
[DataMember]
[FieldProperty(PRIMARY_KEY = 0, COLUMN_TYPE = "VARCHAR2", COLUMN_LENGTH = 100)]
public string DESCRIPTION
{
get;
set;
}
/// <summary>
///
/// </summary>
[DataMember]
[FieldProperty(PRIMARY_KEY = 0, COLUMN_TYPE = "NUMBER", COLUMN_LENGTH = 22)]
public long PRIORITY
{
get;
set;
}
}
}
RD_RADIO_LIST
首先如@心态要好说的IBLL是业务逻辑层接口,而且还实现wcf的服务契约描述。当然了这个接口和实体是使用Easycord生成的。
2、上篇中wcf在架构中起的什么作用?
我们的UI层可能是window、wince。开发语言可能是c#也可能是java。这样我们业务层实现多套肯定不是最好的。很多人在UI层一个操作时会进行数据校验,我通常喜欢将这些校验放在业务层进行。这样我通过wcf提供标准的服务、大家都可以来直接调用不用担心调用前辈的服务自己有什么验证忘记判断,使用wcf客户端不用直接连接数据库,这样安全性、部署的难度都可以有很大改善。
通过上面的解说,大家应该知道,访问wcf可以用性能比较好的TCP协议,也可以使用可以不用担心防火墙等的Http协议,当然有的时候我们确实需要直接连接数据库。这就是我想说的根据IBLL实现TCP,HTTP,BLL模式访问业务层。
不啰嗦啦,直接上图:
设计模式的思想可以肯定的说每个程序员都在用,而且肯定不止一种。只不过有的人是通过gof的相关书籍,有的人是通过同事的经验传授...。总结为每一个设计模式方便大家交流和学习。很多设计模式的名字都忘记了,最近又温故了下gof设计模式,有兴趣的小伙伴们可以来161153385设计模式群一起交流。
在上图中可以看出来至少使用了工厂模式、策略模式、还有模版模式。
工厂模式:InterfaceHelper的Factory方法是你给我一个接口我给你实例,不管你怎么实现。
策略模式:这么说就是见招拆招。你要什么我给你什么模式下的实例。

- switch (_InstanceSource)
- {
- case "BLL": iGetInstance = new BLLGetInstance(); break;
- case "WsHttp": iGetInstance = new WSHttpGetInstance(); break;
- case "WsTcp": iGetInstance = new WSTcpGetInstance(); break;
- }

模版模式:InterfaceHelper在Init中需要初始化加载类和服务和接口。在家每个业务层的时候基本都是一样的,需要加载BLL,IBLL,服务的文件,循环类,保存在字典中。
LoadType(string bllFile, string iBllFile, string serverFile)中就是一个模版。
Init()会通过这个模版初始化字典表中。

- private static void Init()
- {
- string docPath = path + "\\Assembly.xml";
- if (File.Exists(docPath))
- {
- XDocument xdoc = XDocument.Load(docPath);
- foreach (XElement element in xdoc.Element("AssemblyInfos").Elements())
- {
- LoadType(element.Attribute("BLLFileName").Value, element.Attribute("IBLLFileName").Value, element.Attribute("ServeFileName").Value);
- }
- }
- }

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Reflection;
using System.ServiceModel;
using System.Xml.Linq;
namespace Yike.Tool.Instance
{
public class InterfaceHelper
{
private static string _InstanceSource = string.Empty;
private static List<BllTypeRelation> dict = new List<BllTypeRelation>();
private static string path
{
get
{
return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
}
}
public static T Factory<T>()
{
if (string.IsNullOrEmpty(_InstanceSource))
_InstanceSource = GetInstanceSource();
if (dict == null || dict.Count == 0)
Init();
IGetInstance iGetInstance = null;
switch (_InstanceSource)
{
case "BLL": iGetInstance = new BLLGetInstance(); break;
case "WsHttp": iGetInstance = new WSHttpGetInstance(); break;
case "WsTcp": iGetInstance = new WSTcpGetInstance(); break;
}
if (iGetInstance == null)
return default(T);
BllTypeRelation t = dict.Find(d => d.IBll == typeof(T));
if (t != null)
return iGetInstance.GetInstance<T>(t);
else
throw new Exception(path + "不存在");
}
private static string GetInstanceSource()
{
string InstanceSource = string.Empty;
if (ConfigurationManager.AppSettings["InstanceSource"] == null)
InstanceSource = "BLL";
else
InstanceSource = ConfigurationManager.AppSettings["InstanceSource"];
return InstanceSource;
}
private static void Init()
{
string docPath = path + "\\Assembly.xml";
if (File.Exists(docPath))
{
XDocument xdoc = XDocument.Load(docPath);
foreach (XElement element in xdoc.Element("AssemblyInfos").Elements())
{
LoadType(element.Attribute("BLLFileName").Value, element.Attribute("IBLLFileName").Value, element.Attribute("ServeFileName").Value);
}
}
}
private static void LoadType(string bllFile, string iBllFile, string serverFile)
{
if (!File.Exists(path + "\\" + bllFile + ".dll") || !File.Exists(path + "\\" + iBllFile + ".dll"))
return;
Assembly bllAssembly = Assembly.LoadFile(path + "\\" + bllFile + ".dll");
Assembly iBllAssembly = Assembly.LoadFile(path + "\\" + iBllFile + ".dll");
Assembly serverAssembly = null;
if (File.Exists(path + "\\" + serverFile + ".dll"))
serverAssembly = Assembly.LoadFile(path + "\\" + serverFile + ".dll");
Type[] types = bllAssembly.GetTypes();
foreach (Type type in types)
{
string name = type.Name.Replace("BLL", "");
Type t1 = iBllAssembly.GetType(iBllFile + ".I" + type.Name);
Type t2 = null;
if (serverAssembly != null)
t2 = serverAssembly.GetType(serverFile + "." + name + "Server");
if (t1 == null)
continue;
dict.Add(new BllTypeRelation(type, t1, t2));
}
}
}
public class BllTypeRelation
{
public BllTypeRelation(Type bll, Type ibll, Type server)
{
this.Bll = bll;
this.IBll = ibll;
this.Server = server;
}
public Type Bll
{
get;
set;
}
public Type IBll
{
get;
set;
}
public Type Server
{
get;
set;
}
}
public interface IGetInstance
{
T GetInstance<T>(BllTypeRelation t);
}
public class BLLGetInstance : IGetInstance
{
public T GetInstance<T>(BllTypeRelation t)
{
return (T)Activator.CreateInstance(t.Bll);
}
}
public class WSHttpGetInstance : IGetInstance
{
public T GetInstance<T>(BllTypeRelation t)
{
string url = "http://" + ConfigurationManager.AppSettings["ServerIp"] + ":" + ConfigurationManager.AppSettings["ServerPort"] + "/" + t.Server.Name + ".svc";
EndpointAddress ea = new EndpointAddress(url);
return ChannelFactory<T>.CreateChannel(new WSHttpBinding(SecurityMode.None), ea);
}
}
public class WSTcpGetInstance : IGetInstance
{
public T GetInstance<T>(BllTypeRelation t)
{
string url = "net.tcp://" + ConfigurationManager.AppSettings["ServerIp"] + ":" + ConfigurationManager.AppSettings["ServerPort"] + "/" + t.Server.Name + ".svc";
EndpointAddress ea = new EndpointAddress(url);
return ChannelFactory<T>.CreateChannel(new NetTcpBinding(SecurityMode.None), ea);
}
}
}
附源码一份
业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份的更多相关文章
- 利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现(包含增删改查、JavaBean反射原理,附源码)
最近看老罗的视频,跟着完成了利用Java操作MySql数据库的一个框架类JdbcUtils.java,完成对数据库的增删改查.其中查询这块,包括普通的查询和利用反射完成的查询,主要包括以下几个函数接口 ...
- 基于Python接口自动化测试框架+数据与代码分离(进阶篇)附源码
引言 在上一篇<基于Python接口自动化测试框架(初级篇)附源码>讲过了接口自动化测试框架的搭建,最核心的模块功能就是测试数据库初始化,再来看看之前的框架结构: 可以看出testcase ...
- C#/ASP.NET MVC微信公众号接口开发之从零开发(四) 微信自定义菜单(附源码)
C#/ASP.NET MVC微信接口开发文章目录: 1.C#/ASP.NET MVC微信公众号接口开发之从零开发(一) 接入微信公众平台 2.C#/ASP.NET MVC微信公众号接口开发之从零开发( ...
- C#/ASP.NET MVC微信公众号接口开发之从零开发(三)回复消息 (附源码)
C#/ASP.NET MVC微信接口开发文章目录: 1.C#/ASP.NET MVC微信公众号接口开发之从零开发(一) 接入微信公众平台 2.C#/ASP.NET MVC微信公众号接口开发之从零开发( ...
- Asp.net MVC - 使用PRG模式(附源码)
阅读目录: 一. 传统的Asp.net页面问题 二.Asp.net MVC中也存在同样的问题 三.使用PRG模式 四.PRG模式在MVC上的实现 一. 传统的Asp.net页面问题 一个传统的Asp. ...
- Eclipse开发环境debug模式调试断点从jar跳到源码
Eclipse开发环境debug模式调试断点从jar跳到源码 说明:本案例使用jsch-0.1.54.jar和源码做test,项目分成两个,一个是jsch的源码,另一个是测试案例 一.下载JSch.的 ...
- 3.NetDh框架之缓存操作类和二次开发模式简单设计(附源码和示例代码)
前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...
- 使用工厂方法模式实现多数据库WinForm手机号码查询器(附源码)
先讲一下简单工厂模式.工厂方法模式.抽象工厂模式的东西: 简单工厂模式(Simple Factory Pattern):工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关类,也就是说产品 ...
- 2.NetDh框架之简单高效的日志操作类(附源码和示例代码)
前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...
随机推荐
- 使用myeclipse将Javaj项目标ar套餐邂逅classnotfound解决问题的方法
做一件事的今天,该Java项目打包成jar文件.折腾2小时,最终运行jar文件报告classnotfound异常,我觉得程序写入依赖jar包不玩成,但是,我手动添加.或不.网上找了很多办法.或不.后. ...
- 【百度地图API】如何利用地图API制作汽车沿道路行驶的动画?——如何获得道路层数据
原文:[百度地图API]如何利用地图API制作汽车沿道路行驶的动画?--如何获得道路层数据 有几个做汽车导航的朋友问我说,他们想在地图上制作一辆车沿着道路行驶的动画.可是,百度地图的道路数据并没有公开 ...
- 【百度地图API】情人节求爱大作战——添加标注功能
原文:[百度地图API]情人节求爱大作战--添加标注功能 任务描述: 2月2日是除夕,2月14立马来!即将到来的情人节,你想送TA一份什么礼物呢? 不如,在你们居住的地方,画个大大的桃心,表达你对TA ...
- POJ3342——Party at Hali-Bula
Party at Hali-Bula Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5418 Accepted: 192 ...
- VS2015前端工具:NPM和Web Essentials
VS2015前端工具:NPM和Web Essentials 1.写作背景 想在5月份前换个工作环境了,“检讨”一下自己混饭的技术水平和处世的人脉关系,觉得很不给力!为人方面,人各有志也就不纠结了,但本 ...
- php 模拟POST提交的2种方法
1.通过curl函数 $post_data = array(); $post_data['clientname'] = "test08"; $post_data['clientpa ...
- shell 水平测试
http://bbs.chinaunix.net/thread-476260-1-1.html 版权声明:本文博客原创文章,博客,未经同意,不得转载.
- 使用JQUERY操作Radio
发展中经常使用Radio为了实现用户的选择的影响.我在该项目中使用的一些JQUERY操作Radio该方法.这里分享,对于有需要的朋友参考的. 1.变化radio选择.引发一些结果 $("in ...
- [转载]Android中WebView自适应屏幕
webview中右下角的缩放按钮能不能去掉 settings.setDisplayZoomControls(false); //隐藏webview缩放按钮 让Webview加载的页面居中显示有我知道的 ...
- QC邮件转发工具Mail Direct安装配置手册
QC邮件转发工具Mail Direct安装配置手册 2010-06-11 10:00:56| 分类: 软件测试 | 标签: |举报 |字号大中小 订阅 QC邮件转发工具安装配置手册 由于公司没有独立的 ...