很多人都研究过petshop,我开始认识分层架构也是从研究这个petshop开始的。但是我发现很多人一谈三层架构就是

petshop那一套东西。实体类,DAL,BLL那一套东西。首先我不否认petshop这个架构整体的设计的合理性。但是这个合理性也是在一

定的项目环境下来说的。我觉得petshop这个架构只适合比较小的项目。系统的大部分需求只是对数据库的CRUD操作。而且业务逻辑

变化变化可能性很小的情况。

看过企业架构模式的应该知道。Petshop这个业务逻辑层采用的是表模块(table module),一个表对应一个类,负责这个表

相关的业务逻辑。数据访问层是表入口(table gateway),也是一个表对一个类,负责这个表的所有crud操作。还定义了实体类用

来保存数据库中取出的数据,用来在各层间传递。这种设计数据和行为分别放到了不同的类中。这个确实违背了oo的原则(数据和

数据相关的行为应该放到一起).业务逻辑层中业务逻辑操作类还都是静态方法。

从以上分析可以看出这个架构的一大隐患就是把自己弄的和oo保持了很远的距离。首先是行为和数据的分离。再者就是业务逻辑类

中的静态方法。这些都让oo的核心特性,继承和多态没办法应用。没了oo,设计模式中那些封装变化点的手法也就派不上用处了。

做企业应用的一定都有体会,变化那个快啊!唯一不变的就是变化。想给petshop想几个需求变化来说明这个架构不适合复杂业务逻

辑项目,还真是不容易。干脆就拿我现在面对的项目说事吧。这个是我们公司的网站。主要是卖我们公司的产品。基本的业务流程是

,用户填写一些和产品相关的信息。联系人,邮箱,地址等等。然后处理订单的流程如下。1.根据用户选择的产品做不同的验证(

因为不同产品的需要的验证的数据项和验证规则都不一样)。2.根据不同的产品计算价格3根据不同的产品调用库存系统接口.(主

要是传递的参数不一样)。4.根据不同产品的保存订单信息和产品信息。目前系统的设计基本这样的。设计使用事务脚本来处理这个流程的。基本上每个环节都对应一

个方法。Buy方法调用依次调用validate,produce,saveorder方法。然后每个方法会在内部用switch和if来判断是那个产品然后做出相应的处理。很难相信这种代

码能运行这么长的时间。由于我们公司产品线变化非常的频繁。所以基本上每添加新的产品都要修改所有以上方法。由于频繁的修

改导致了代码的严重可读性差。每个方法都愈来越长,if语句愈来愈诡异。有些下线的产品代码其实该清除的。 说了这么多我觉得

最大的缺陷是组织业务逻辑的方法不合适。我现在被安排维护这些代码。每改一个新需求,我都心里发虚啊。怕自己弄错了if块。

还好领导们也认为旧的系统维护效率太低了。要求重新设计系统。我觉得应该把业务逻辑使用领域模型来组织。每个行为

不一样的产品都应该有自己的类。然后对产品建立一个类体系。抽象出每个环节和具体某个产品相关的行为到一个类中。比如

ProductA应该有Validate,GetProduceParameter,等等,这几个方法。来实现验证自己,获取库存调用接口参数,和获取订单相关信

息的方法。这样buy方法就可以把这些行为委托给具体的产品类。自己就负责流程管理就行了。以后新产品来了,就对新产品建立个

新类。这样这个业务层也就对修改封闭对扩展开放了。这个没oo确实很难办。理想总是很美好的。几个项目主管和其他同事推崇的

架构方案居然是和petshop一样的架构。Petshop组织业务逻辑的方式虽说比事务脚本好了点。但是它的缺点也是很多啊。就我知道

的,这个架构对数据库表耦合的很紧。基本都是实体类和表一一对应,然后字段和属性也一致。网上很多生成实体类的方法也都是

根据数据库表的元数据信息自动生成的。虽说弄了三层但是那一层也没逃脱对数据库结构的依赖。对数据库结构的变动会导致所有

层的修改。另外 petshop的那个抽象工厂用的也有点多余把。Ado.net2.0已经实现了这个模式,我们在数据访问层直接用

DBConnection,DBCommond这些抽象类就行了。所以我觉得这个petshop纯粹是个演示架构和微软技术的一个花架子。具体到每个不同

的项目,都有自己的项目环境。生搬硬套petshop也是很stupid.说实在的我认为对于petshop那样的项目需求也根本费不上petshop

那样的架构。

我心目中一个复杂企业应用的架构

我也质疑下petshop的更多相关文章

  1. .NET 三层架构的简单规划

    今天心血来潮简单看了下petshop4.0的源代码,他就是用三层架构来实现的.现在简单的做下总结. 首先我们先看下petshop的三层架构. 1 WEB 表示层 2 Model 业务实体 3 BLL ...

  2. 2017-10-27模拟赛2-T1 选举(election.*)

    Description 题目描述 C国的总统选举委员会最近遇到了一些麻烦. 他们在统计各省对H先生的支持率(百分比)时,把支持率四舍五入到了整数.等他们公布结果后,该国媒体发现这些省份的支持率之和不等 ...

  3. C++程序结构---1

    C++ 基础教程Beta 版 原作:Juan Soulié 翻译:Jing Xu (aqua) 英文原版 本教程根据Juan Soulie的英文版C++教程翻译并改编. 本版为最新校对版,尚未定稿.如 ...

  4. 用SignalR 2.0开发客服系统[系列4:负载均衡的情况下使用SignalR]

    前言 交流群:195866844 目录: 用SignalR 2.0开发客服系统[系列1:实现群发通讯] 用SignalR 2.0开发客服系统[系列2:实现聊天室] 用SignalR 2.0开发客服系统 ...

  5. iPhone 6 被盗记录二【写在315前夕:苹果售后福州直信创邺在没有三包的情况下帮小偷翻新、助力小偷换机销赃!无视王法。让人震惊,痛心,憎恨!消费者很受伤很无奈】

    投诉公司: 北京直信创邺数码科技有限公司  标题: 写在315前夕:苹果售后在没有三包的情况下帮小偷翻新.助力小偷换机销赃!无视王法.让人震惊,痛心,憎恨!消费者很受伤很无奈 期望: 还我手机,或者赔 ...

  6. web应用安全防御100技 好书再次阅读, 变的只是表象,被概念迷惑的时候还是静下心来回顾本质

    如何进行web应用安全防御,是每个web安全从业者都会被问到的问题,非常不好回答,容易过于肤浅或流于理论,要阐明清楚,答案就是一本书的长度.而本文要介绍一本能很好回答这个问题的优秀书籍——<we ...

  7. 分享下对JAVA程序员成长之路的总结<转>

    我也搞了几年JAVA了,由于一向懒惰,没有成为大牛,只是一普通程序猿,手痒来给新人分享下从新手成长为老鸟的已见.   首先初识语法的阶段,必须要学会怎么操作对象,操作if和for,操作list set ...

  8. 你是否还在质疑EF的性能

    1. 写在前面的话 一直没有写博客的习惯,感觉太浪费时间,没有那么多精力,其实仔细一想,写博客是一种习惯,也是一种心境,同时也是对自己所掌握的知识结构的一个梳理过程,对自己知识体系的一个巩固,同时也是 ...

  9. 基于Node的PetShop,oauth2认证RESTful API

    前篇 - 基本认证,用户名密码 后篇 - OAuth2 认证 前文使用包passport实现了一个简单的用户名.密码认证.本文改用oauth2来实现更加安全的认证.全部代码在这里. OAUTH2 用户 ...

随机推荐

  1. python中通过xlwt、xlrd和xlutils操作xls

    xlwt模块用于在内存中生成一个xls/xlsx对象,增加表格数据,并把内存中的xls对象保存为本地磁盘xls文件; xlrd模块用于把本地xls文件加载到内存中,可以读取xls文件的表格数据,查询x ...

  2. 机器学习: 特征脸算法 EigenFaces

    人脸识别是机器学习和机器视觉领域非常重要的一个研究方向,而特征脸算法是人脸识别里非常经典的一个算法,EigenFaces 是基于PCA (principal component analysis) 即 ...

  3. 使用 WinSCP(下载) 上文件到 Linux图文教程

        问题导读: 1.如何远程链接? 2.如何上传文件? 3.如何对立面的文件进行操作? 4.什么情况下会链接失败? https://yunpan.cn/cYWtNMycjeVPv 访问密码 4f7 ...

  4. Linux 终端显示 Git 当前所在分支

    function git_branch { branch="`git branch 2>/dev/null | grep "^\*" | sed -e " ...

  5. php获取YouTube视频信息的方法

    YouTube的视频地址格式https://www.youtube.com/watch?v=[VIDEO_ID]例子:https://www.youtube.com/watch?v=psvkyf3Pz ...

  6. 创建calico网络报错client response is invalid json

    使用docker创建calico网络失败. # docker network create --driver calico --ipam-driver calico-ipam testcalico E ...

  7. const_cast标准转换运算符

    #include <iostream> using namespace std; class A { public: A() { a=; } public: int a; }; void ...

  8. Levko and Array

    题意: 有一长度为n的正整数序列,你可以选择K个数字任意改变它,使得$max \{ a(i+1) - a(i) \} $ 最小,求最小值. 解法: 1.$O(n^2log(MAX_A) )$,考虑二分 ...

  9. 3-C++程序的结构1.1

    数据的共享和保护机制是C++的重要特性之一. 1.标识符的作用域与可见性 作用域讨论的是标识符的有效范围,可见性是讨论标识符是否可以被引用. a.作用域 作用域是一个标识符在程序正文中有效的区域.C+ ...

  10. struts2 中的 addActionError 、addFieldError、addActionMessage的方法

    addActionError .addFieldError.addActionMessage都是ActionSupport的方法 一.addActionError("错误内容"): ...