当前位置: 首页 > wzjs >正文

科技公司企业网站源码上海平面设计公司

科技公司企业网站源码,上海平面设计公司,微信开店哪个平台好,网站访问量大 处理文章目录 贫血模型和充血模型软件开发中的"开卡"和"验卡"面向过程代码层间依赖原则和依赖倒置问题一:OrgDto违反层间依赖原则(依赖倒置)问题二:Repository的调用违反层间依赖原则 贫血模型和充血模型 贫血模…

文章目录

  • 贫血模型和充血模型
  • 软件开发中的"开卡"和"验卡"
  • 面向过程代码
  • 层间依赖原则和依赖倒置
    • 问题一:OrgDto违反层间依赖原则(依赖倒置)
    • 问题二:Repository的调用违反层间依赖原则

贫血模型和充血模型

  • 贫血模型(Anemic Domain Model)指领域对象中只有数据,没有行为,由于过于单薄,就好像人贫血了一样,显得不太健康。这种风格违背了面向对象的原则。
  • 富领域模型(Rich Domain Model):领域对象里既包含数据,也包含行为。
  • 充血模型与富领域模型不同,为避免混淆,把贫血模型称为面向过程或者过程式编程,把富领域模型称为面向对象或对象式编程
  • 面向对象和面向过程的关系图:
    在这里插入图片描述
  • 在纯粹的面向对象和纯粹的面向过程之间有一个广阔的“灰色地带”变化非常多,难以穷尽。这两个极端都不是我们要追求的,我们要做的是找到其中的一个平衡点。
  • 寻找平衡点的原则:在领域对象不直接或间接访问数据库的前提下,尽量面向对象。

软件开发中的"开卡"和"验卡"

  • 开卡(Kick-off):在正式开始开发一个用户故事或功能前,开发团队与业务代表(如产品负责人、领域专家)进行的确认会议。
  • 验卡(Desk Check):在代码开发完成后但尚未提交正式测试前,开发人员与测试人员或业务代表进行的快速验证。
  • 经过讨论,发现之前项目中新增几个业务规则,如同一个组织里,不能有两个同名的下级组织。也就是说,假如“金融开发中心”下面已经有“开发一组”了,那么新加的开发组,不能也叫“开发一组”。
规则编号模块规则描述示例影响的主要功能
R008组织管理对上下级组织的规定:
* 开发组上下级只能是研发中心
* 开发组和直层部门没有下级
在企业下增加研发中心A是可以的,但想在企业下直接增加研发组B,则无法做到组织修改组织
R013组织管理企业是在创造中的时候建立好的,因此不能单独创建企业组织修改组织
R014组织管理组织必须有组织类别组织修改组织
R015组织管理组织类别必须有效组织修改组织
R016组织管理组织负责人不可为空,如果有的话,则必须是一个在职员工(含试用期)创建某组织时,指定了李国庆作为负责人,但在系统中,李国庆已离职,系统提示错误组织修改组织
R017组织管理上级组织必须有效(不能为撤销状态)组织修改组织
R018组织管理组织必须有名称组织修改组织
R019组织管理同一级组织的下级组织不能重名“金融研发中心”下已经有了“研发一组”,不允许在该中心下新建一个也叫“研发一组”的研发组所有操作
R020组织管理租户必须有效组织修改组织
  • 通过表格分析发现,我们需要在实体中增加状态属性来表达“有效”、“终止”等状态。租户、组织、组织类别、员工、客户、合同、项目等实体中都增加状态,并且在数据库里添加相应的字段。

面向过程代码

在这里插入图片描述

  • 总体逻辑如上图
    第一步,适配器层里的 OrgController 通过 Restful API 接收到添加组织的请求,请求数据封装在 OrgDto 里。
    第二步,Controller 以 OrgDto 为参数,调用应用层里的 OrgService 服务中的 addOrg() 方法进行处理。
    第三步,OrgService 对参数进行校验,过程中会调用适配器层里的 Repository 来访问数据库。
    第四步,OrgService 创建领域层里的 Org 对象,也就是组织对象。
    第五步,OrgService 调用 OrgRepository 把组织对象存到数据库,并回填组织 id。
    第六步,OrgService 把组织对象装配成 DTO,返回给控制器,控制器再返回给前端。整个过程还是比较直白的,目前主要逻辑都集中在 OrgService 里,也就是第三步到第六步。

  • 领域层组织对象类com/yang/system/domain/orgMng/Org.java

@Data
public class Org {private Long id;private Long tenantId;private Long superiorId;private String orgTypeCode;private Long leaderId;private String name;private OrgStatus status;// 使用枚举类型private LocalDateTime createdAt;private Long createdBy;private LocalDateTime lastUpdatedAt;private Long lastUpdatedBy;public Org() {status = OrgStatus.EFFECTIVE;  //组织的初始状态默认为有效}
}
  • 应用层组织对象类com/yang/system/application/orgMng/OrgDto.java
@Data
public class OrgDto {private Long id;private Long tenantId;private Long superiorId;private String orgTypeCode;private Long leaderId;private String name;private String status;private LocalDateTime createdAt;private Long createdBy;private LocalDateTime lastUpdatedAt;private Long lastUpdatedBy;
}
  • 状态枚举类com/yang/system/domain/orgMng/OrgStatus.java(解决层间依赖后的位置)
public enum OrgStatus {EFFECTIVE("生效中", 1),TERMINATING("终止中", 2);private final String description; // 描述private final int code; // 状态码// 构造函数OrgStatus(String description, int code) {this.description = description;this.code = code;}// 获取描述public String getDescription() {return description;}// 获取状态码public int getCode() {return code;}// 根据状态码获取枚举实例public static OrgStatus getByCode(int code) {for (OrgStatus status : OrgStatus.values()) {if (status.getCode() == code) {return status;}}throw new IllegalArgumentException("Invalid status code: " + code);}@Overridepublic String toString() {return this.description;}}

层间依赖原则和依赖倒置

  1. 先查看被动适配器中的组织控制类com/yang/system/adapter/driven/restful/orgMng/OrgController.java
@RestController
public class OrgController {private  final OrgService orgService;@Autowiredpublic OrgController(OrgService orgService) {this.orgService = orgService;}@PostMapping("/api/organizations")public OrgDto addOrg(@RequestBody OrgDto request) {Long userId=request.getTenantId();return orgService.addOrg(request,userId);}
}
  1. 再查看应用层的OrgService
@Service
public class OrgService {private final UserRepository userRepository;private final TenantRepository tenantRepository;private final OrgTypeRepositoryJdbc orgTypeRepositoryJdbc;private final OrgRepositoryJdbc orgRepositoryJdbc;private final EmpRepositoryJdbc empRepositoryJdbc;@Autowiredpublic OrgService(UserRepository userRepository,TenantRepository tenantRepository,OrgRepositoryJdbc orgRepositoryJdbc,EmpRepositoryJdbc empRepositoryJdbc,OrgTypeRepositoryJdbc orgTypeRepositoryJdbc) {this.userRepository = userRepository;this.tenantRepository = tenantRepository;this.orgRepositoryJdbc = orgRepositoryJdbc;this.empRepositoryJdbc = empRepositoryJdbc;this.orgTypeRepositoryJdbc = orgTypeRepositoryJdbc;}public OrgDto addOrg(OrgDto request, Long userId) {validate(request,userId);Org org = buildOrg(request, userId);org= orgRepositoryJdbc.save(org);return buildOrgDto(org);}private OrgDto buildOrgDto(Org org) {// 将领域对象的值赋给DTO...if (org == null) {return null;}OrgDto orgDto = new OrgDto();BeanUtils.copyProperties(org, orgDto);orgDto.setStatus(org.getStatus().name());return orgDto;}private Org buildOrg(OrgDto request, Long useId) {// 将DTO的值赋给领域对象...Org org = new Org();BeanUtils.copyProperties(request, org);org.setCreatedBy(useId);return org;}private void validate(OrgDto request, Long userId) {//进行各种业务规则的校验,会用到上面的各个Repository...}
}

问题一:OrgDto违反层间依赖原则(依赖倒置)

  • OrgDto是应用服务中addOrg方法的入口参数类型,所以应用层依赖OrgDto,而OrgDto又在适配器层。换言之,应用层依赖适配器层违反了内层不能依赖外层的原则。
  • 解决方法:将OrgDto移动到应用层。
    在这里插入图片描述

问题二:Repository的调用违反层间依赖原则

  • Repository的调用违反层间依赖原则。仓库放在适配器层,而应用层调用仓库,造成应用层对适配器层的依赖,再一次违反了层间依赖规则。
  • 解决方法:
    • 第一步,从仓库抽出一个接口,原来的仓库成为了这个接口的实现类。
    • 第二步,把这个接口移动到领域层。
      在这里插入图片描述
  • 仓库接口都按照 XxxRepository 的形式命名。而仓库的实现是在接口名字的后面加上 Jdbc ,在目前的例子里只是用Jdbc 来做持久化。
  • OrgRepository接口类的内容如下:
import java.util.Optional;public interface OrgRepository {Org save(Org org);Optional<Org> findByIdAndStatus(long tenantId, Long id,OrgStatus status);int countBySuperiorAndName(long tenantId, Long superiorId, String name);boolean existsBySuperiorAndName(Long tenant, Long superior, String name);
}
  • OrgRepositoryJdbc类的实现
@Repository
public class OrgRepositoryJdbc implements OrgRepository {@Overridepublic Org save(Org org) {return null;}@Overridepublic Optional<Org> findByIdAndStatus(long tenantId, Long id, OrgStatus status) {return Optional.empty();}@Overridepublic int countBySuperiorAndName(long tenantId, Long superiorId, String name) {return 0;}@Overridepublic boolean existsBySuperiorAndName(Long tenant, Long superior, String name) {return false;}
}

  • 解决方法原理分析:从 OrgService 到领域层中仓库接口的三个箭头。它们实际上代表了 OrgService 中用这三个接口定义的属性。由于 OrgService 可以通过属性导航到仓库,而仓库中并没有属性能够导航到 OrgService,所以关联是单向的。
  • 通过抽取和移动接口,变成适配器依赖别的层,依赖关系被“倒过来”了。所以这种技巧就称为依赖倒置(dependency inversion),是面向对象设计中常见的调整依赖关系的手段。
    在这里插入图片描述

文章转载自:

http://DyycaKM7.xsszn.cn
http://g3598B9J.xsszn.cn
http://cVUT7LVy.xsszn.cn
http://QMjqlNwB.xsszn.cn
http://PDDeUFKV.xsszn.cn
http://IklWz6DO.xsszn.cn
http://HznZXw5L.xsszn.cn
http://993stB7S.xsszn.cn
http://kPTjbQnV.xsszn.cn
http://ptTKZx8G.xsszn.cn
http://D34ABDTt.xsszn.cn
http://zrW2jAyx.xsszn.cn
http://1Mi5n8Mm.xsszn.cn
http://09tJgqjC.xsszn.cn
http://FSbeyjx1.xsszn.cn
http://xMP0VTOK.xsszn.cn
http://qgwbN5qR.xsszn.cn
http://DGAI8C6v.xsszn.cn
http://eQSpLmY1.xsszn.cn
http://ptcJXINo.xsszn.cn
http://QgR6RK5b.xsszn.cn
http://U0m9xbuV.xsszn.cn
http://YsMJK9ue.xsszn.cn
http://4wlNvjIy.xsszn.cn
http://VelpQ6ZV.xsszn.cn
http://Z7Pb0kWy.xsszn.cn
http://xL3Alk08.xsszn.cn
http://FENHfwZu.xsszn.cn
http://tI8ynzNy.xsszn.cn
http://jIJB4RhB.xsszn.cn
http://www.dtcms.com/wzjs/685711.html

相关文章:

  • 做网站维护承包合同北京网站备案号
  • 专门查企业信息的网站wordpress pdf预览
  • wordpress登录链接昆明网站快速优化排名
  • wordpress跳转链接地址seo wordpress 主题
  • 株洲建设公司网站网站建设策划方案t
  • 临沂网站制作案例网站建设朋友圈
  • 百度公司官方网站陕西省交通建设厅网站
  • 塔城市建设局网站杭州久邦电力建设有限公司网站
  • 宜春网站建设联系方式网站经营性备案难不难
  • 做淘宝内部优惠券网站要钱么菜鸟零基础如何自学编程
  • 做盗文网站大创意网站
  • 网站优化提升排名免费公司网址怎么注册
  • 美食网站 原型 html 下载mui做浏览器网站跳转
  • 禅城做网站宁波城乡建设局管方网站
  • 顺德 网站设计建设项目银行网站
  • 深圳建设网站商天眼查官网查询企业
  • 开发一个网站的流程福州网
  • 怎样在阿里巴巴做网站北京手机网站设计公司
  • 软件网站关键词优化做网站公司没签合同
  • 企业做商城网站需要什么资质网站建设ssc源码平台
  • 漯河网站建设漯河什么网页传奇好玩
  • 购买完域名后怎么做网站英文网站制作
  • 大连华南网站制作公司企业公众号以及网站建设
  • 网站的优化排名怎么做营销网站的优势是什么
  • 做新媒体应该关注什么网站重庆网站建设必选承越
  • 建设网站项目总结wordpress音频播放器
  • 富阳住房和城乡建设部网站免费做图片链接网站
  • 织梦可以做婚纱影楼网站吗公司做网站需要准备哪些资料
  • 网站效果图确认表学校建设网站的意义
  • 深圳做网站最好的公热门传奇网页游戏排行榜