Preface:

合理的软件架构设计其好处是不言而喻的,系统具有清晰的软件结构,良好的可扩展性,类的职能单一明确,系统的复杂度底。此前的一个实际项目中总结了些关于OO设计的实际应用,主要是围绕‘高内聚及松耦合’,‘开闭原则’的一些应用。

Problem: 

目前有一个实际应用放在我们面前,为一个银行现有BI系统开发WebService对外数据接口应用,数据交换方式以预定请求及响应报文来完成,要求可以数据接口系统跨平台使用。即远程客户端发来一种XML数据请求报文,系统按类型执行查询,然后返回XML数据响应报文。

问题也浮出水面,通常此类系统中我们可以想像到,其中一定会有一系列的if else来判断是何种请求报文,然后再执行对应的动作,但我们如果我们这样设计,系统就违反了开放-封闭原则 (OCP,Open-Close Principle),日后的扩展一定需要修改原有代码,而我们期望的是日后添加一种新报文后,只在系统中扩展新的请求、查询及响应对象来实现新需求。

带着问题思考解决办法...

补充:敏捷设计扩展知识手册

拙劣设计的症状:

1.僵化性(Rigidity):设计难以改变。很难对系统进行改动,因为每个改动都会迫使许多对系统其他部分的其他改动。

2.脆弱性(Fragility):设计易于遭到破坏。对系统的改动会导致系统中和改动的地方在概念上无关的许多地方发现问题。3.牢固性 (Immobility):设计难以重用。很难解开系统的纠结,使之成为一些可在其他系统中重用的组件。

4.粘滞性(Viscosity):难以做正确的事情。做正确的事情比做错误的事情要困难。

5.不必要的复杂性(Needless Complexity):过分设计。设计中包含有不具有任何直接好处的基础结构。

6.不必要的重复性(Needlsee Repetition):滥用复制/粘贴。设计中包含有重复的结构,而该重复的对象本可以使用单一的抽象进行统一。

7.晦涩性(Opacity):很难阅读、理解。没有很好的表现出意图。

面向对象的设计原则:

1.单一职责原则 (SRP,Single Resposibility Principle)

2.开放-封闭原则 (OCP,Open-Close Principle)

3.Liskov替换原则 (LSP,Liskov Principle)

4.依赖倒置原则 (DIP,Dependicy Independent Priciple)

5.接口隔离原则 (ISP,Interface Seperation Principle)

Solution:

我们初步的想法是,系统接受到一种XML请求后将其转换成请求对象,类似多态的方法,根据不同的请求对象由查询工厂来创建返回不同的查询处理类,再由查询处理类返回填充好的数据响应对象,最后转换成XML响应报文。由此思路,我们完成了UML类图设计,如下:

首先是RemoteQueryService 接口,系统对外的WS服务由此接口完成。

  1. /**
  2. * 类说明: WS远程服务接口<br>
  3. * 创建时间: 2009-11-6 上午10:07:55<br>
  4. *
  5. * @author Seraph<br>
  6. * @email seraph115@gmail.com<br>
  7. *
  8. */
  9. public interface RemoteQueryService {
  10. /**
  11. * 功能说明: <br>
  12. * 创建者: Seraph<br>
  13. * 创建时间: 2009-11-6 上午10:08:09<br>
  14. *
  15. * @param request
  16. * @return
  17. */
  18. @Profiled(tag = "RemoteQueryService")
  19. public String doQuery(String request);
  20. }

RemoteQueryServiceImpl 类是此接口的实现,接口方法为接受一种XML请求报文然后返回响应报文。

RegisterContainer 类,在系统初始化时完成不同请求所对应的查询处理类的注册。

QueryFactory 类,根据不同的请求对象返回不同的查询处理类。

ParserRobot 类,负责将XML请求转换为Java请求对象,将Java响应对象转换为XML报文。

QueryProvider 抽象类,是不同种查询处理类的父类。

Request 类,是请求对象的父类。

Response 类,是响应对象的父类。

其中QueryProvider 类,doQuery抽象方法由继承后的子类实现,用来实现不同种报文的查询处理方法,代码为:

  1. /**
  2. * 类说明: <br>
  3. * 创建时间: 2009-11-6 上午10:21:30<br>
  4. *
  5. * @author Seraph<br>
  6. * @email seraph115@gmail.com<br>
  7. *
  8. */
  9. @Service
  10. public abstract class QueryProvider {
  11. private QueryDaoSupport queryDaoSupport;
  12. private SqlProvider sqlProvider;
  13. public abstract Response doQuery(Request request) throws BrwsException;
  14. public QueryDaoSupport getQueryDaoSupport() {
  15. return queryDaoSupport;
  16. }
  17. public void setQueryDaoSupport(QueryDaoSupport queryDaoSupport) {
  18. this.queryDaoSupport = queryDaoSupport;
  19. }
  20. public SqlProvider getSqlProvider() {
  21. return sqlProvider;
  22. }
  23. public void setSqlProvider(SqlProvider sqlProvider) {
  24. this.sqlProvider = sqlProvider;
  25. }
  26. }

由UML图中,我们可以看到Request , QueryProvider , Response有许多对应的子类,而每个子类都是一种报文类型,也就是系统所能提供的查询服务。所以目前的架构设计下,日后添加一种新报文将很容易,只需要实现一组 Request, QueryProvide及Response就可以完成新报文的实现,从而达到了松耦合、可扩展的设计。

Webservice银行报文接口设计的更多相关文章

  1. 优秀的API接口设计原则及方法(转)

    一旦API发生变化,就可能对相关的调用者带来巨大的代价,用户需要排查所有调用的代码,需要调整所有与之相关的部分,这些工作对他们来说都是额外的.如果辛辛苦苦完成这些以后,还发现了相关的bug,那对用户的 ...

  2. 基于PCIe的高速接口设计

    基于PCIe的高速接口设计 由 judyzhong 于 星期四, 03/03/2016 - 13:49 发表 作者:李晓宁,姚远程,秦明伟 2016年微型机与应用第1期 摘要:PCIe总线是第三代I/ ...

  3. C#winForm调用WebService的远程接口

    Web Service 的创建简单编码.发布和部署 上一篇详细概述了WebService的创建,编码,发布和部署,那么作为客户端的程序如何访问远程端的WebService 接下来看一下具体步骤:   ...

  4. 数据仓储之DLL层接口设计

    一.接口设计 1.1. IBaseRepository.cs public interface IBaseRepository<T> { T Add(T entity); bool Upd ...

  5. RESTful接口设计原则/最佳实践(学习笔记)

    RESTful接口设计原则/最佳实践(学习笔记) 原文地址:http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api 1 ...

  6. Web API接口设计经验总结

    在Web API接口的开发过程中,我们可能会碰到各种各样的问题,我在前面两篇随笔<Web API应用架构在Winform混合框架中的应用(1)>.<Web API应用架构在Winfo ...

  7. Verilog学习笔记简单功能实现(七)...............接口设计(并行输入串行输出)

    利用状态机实现比较复杂的接口设计: 这是一个将并行数据转换为串行输出的变换器,利用双向总线输出.这是由EEPROM读写器的缩减得到的,首先对I2C总线特征介绍: I2C总线(inter integra ...

  8. atitit.基于http json api 接口设计 最佳实践 总结o7

    atitit.基于http  json  api 接口设计 最佳实践 总结o7 1. 需求:::服务器and android 端接口通讯 2 2. 接口开发的要点 2 2.1. 普通参数 meth,p ...

  9. App接口设计

    关于APP接口设计 http://blog.csdn.net/gebitan505/article/details/37924711/

随机推荐

  1. 关于common.js里面的module.exports与es6的export default的思考总结

    背景 公司项目需要裁切功能,基于第三方图片裁切组件vue-cropper(0.4.0版本),封装了图片裁切组件(picture-cut)(放在公司内部组件库,仅限于公司内部使用) 在vue-cropp ...

  2. laravel中soapServer支持wsdl的例子

    最近在对接客户的CRM系统,获取令牌时,要用DES方式加密解密,由于之前没有搞错这种加密方式,经过请教了"百度"和"谷歌"两个老师后,结合了多篇文档内容后,终于 ...

  3. 洛谷 P2104 二进制

    P2104 二进制 题目描述 小Z最近学会了二进制数,他觉得太小的二进制数太没意思,于是他想对一个巨大二进制数做以下 4 种基础运算: 运算 1:将整个二进制数加 1 运算 2:将整个二进制数减 1 ...

  4. 华为:一张图看懂 HBase

    来自为知笔记(Wiz)

  5. [Python] Use a Python Generator to Crawl the Star Wars API

    In this lesson, you will be introduced to Python generators. You will see how a generator can replac ...

  6. [React] Make Controlled React Components with Control Props

    Sometimes users of your component want to have more control over what the internal state is. In this ...

  7. HDU 2444 The Accomodation of Students 二分图判定+最大匹配

    题目来源:HDU 2444 The Accomodation of Students 题意:n个人能否够分成2组 每组的人不能相互认识 就是二分图判定 能够分成2组 每组选一个2个人认识能够去一个双人 ...

  8. Vue进阶之事件处理器

    过滤 <html> <head> <meta charset="UTF-8"> <meta name="viewport&quo ...

  9. rowcount和@@rowcount的区别

    1 rowcount rowcount的作用就是用来限定后面的sql在返回指定的行数之后便停止处理,比如下面的示例, set rowcount 10select * from 表A 这样的查询只会返回 ...

  10. js中迭代的常用几种方法

    var arr = [1,3,2,5,3]; //forEach 两个参数,第一个为数组内容,第二个为数组下标arr.forEach(function(item,index) { console.lo ...