MVC基础——市场管理系统(三)Clean Architecture

news/2024/12/11 20:58:42/

文章目录

  • 项目地址
  • 五、Clean Architecture
    • 5.1 user cage driven
      • 5.1.1创建CoreBusiness
    • 5.2 创建UseCases
      • 5.2.1 创建CategoriesUseCases
        • 1. 创建`VeiwCategoriesUseCase`获取所有Cagegory
      • 5.2.2. 实现ICategoryRepository接口
        • 3. 实现获取所有Category的方法
        • 4. 实现获取一个Cagegory的方法
        • 5. 实现编辑Category的方法
        • 6. 实现获取删除Category的方法
      • 5.2.3 创建ProductsUseCases
        • 1. 创建一个AddProductUseCase
        • 2. 使用快捷键生成IProductRepository接口
        • 3. 通过快捷键生成接口对应的AddProduct方法
        • 4. 通过同样的方式,将剩下的几个UseCase完成
        • 5. 通过快捷键将UseCase 提取成为接口
    • 5.3 创建Plugins
      • 5.3.1 实现一个内存存储的plugin
    • 5.4 使用IOC在Controllers里
      • 5.4.1 将CategoriesUseCases里的实现抽离成为接口
      • 5.4.2 在CategoriesContollers里使用
      • 5.4.3 使用相同的方法将Categories相关的usecase抽离成为接口


项目地址

  • 教程作者:
  • 教程地址:
  • 代码仓库地址:
  • 所用到的框架和插件:
dbt 
airflow

五、Clean Architecture

  1. usecase driven
  2. plugin based

5.1 user cage driven

5.1.1创建CoreBusiness

业务实体存放的类

  1. 创建一个class library,CoreBusiness
  2. Models文件夹下的Categories.csProducts.cs以及Transactions.cs三个实体类,移动到CoreBusiness类库里,并修改他们的namespace

5.2 创建UseCases

  • 创建UseCases类库

5.2.1 创建CategoriesUseCases

  • 从功能出发,如果我们需要一个处理Categories相关的业务,需要对Categories数据表有哪些操作
  1. 查询出所有的Categories, ViewCategoriesUseCase.cs
  2. 查询单个Category的信息,ViewSelectedCategoryUseCase.cs
  3. 添加单个Category,AddCategoryUseCase.cs
  4. 编辑单个Category,EditCategoryUseCase.cs
  5. 删除单个Category,DeleteCategoryUseCase.cs
1. 创建VeiwCategoriesUseCase获取所有Cagegory
  1. 在UseCases类库里,创建文件夹CategoriesUseCases文件夹
  2. 在该文件夹下添加ViewCategoriesUseCase.cs
  3. ViewCategoriesUseCase.cs 只有一个公共的方法对外使用,因为他的功能显示Category的列表
  4. 添加对CoreBusiness的引用
  5. 创建一个返回所有Category的方法Excute()
public IEnumerable<Category> Excute()
{
}
  1. 使用构造方法,注入一个ICategoryRepository,这里这个接口还没有实现,只是我们知道我们需要用到这个接口提供的方法来获取我们想要的数据,这就是usecase driven的核心
namespace UseCases.CategoriesUseCases
{public class ViewCategoriesUseCase{private readonly ICategoryRepository _categoryRepository;public ViewCategoriesUseCase(ICategoryRepository categoryRepository){this._categoryRepository = categoryRepository;}public IEnumerable<Category> Excute(){//需要用到这个接口给我们提供的GetCategories方法获取数据return _categoryRepository.GetCategories();}}
}
  1. 至此,就完成了一个简单的Use Case Driven,在UseCases层,我们关心,接口哪里来,在哪里实现,只关心我需要这个接口以及接口能解决问题的方法,只是接口的使用者;

5.2.2. 实现ICategoryRepository接口

定义了与 Category 实体相关的操作,所有关于Category的操作都在这个接口上,供给plugins使用

在这里插入图片描述

1 . 在UseCases里创建文件夹DataStorePluginInterfaces
2. 创建ICategoryRepository.cs

using CoreBusiness;namespace UseCases.DataStorePluginInterfaces
{public interface ICategoryRepository{}
}
  1. 然后通过CategoriesUseCases里创建的方法,来逆向实现接口

在这里插入图片描述

3. 实现获取所有Category的方法
  • ViewCategoriesUseCase.cs里实现GetCategories()方法,该类只负责获取所有的Category列表,单一职责
using CoreBusiness;
using UseCases.DataStorePluginInterfaces;namespace UseCases.CategoriesUseCases
{public class ViewCategoriesUseCase{private readonly ICategoryRepository _categoryRepository;public ViewCategoriesUseCase(ICategoryRepository categoryRepository){this._categoryRepository = categoryRepository;}public IEnumerable<Category> Excute(){return _categoryRepository.GetCategories();}}
}
4. 实现获取一个Cagegory的方法
  • 创建ViewSelectedCategoryUseCase.cs,该类只负责获取一个Cagegory

namespace UseCases.CategoriesUseCases
{public class ViewSelectedCategoryUseCase{private readonly ICategoryRepository _categoryRepository;public ViewSelectedCategoryUseCase(ICategoryRepository categoryRepository){this._categoryRepository = categoryRepository;}public Category Excute(int categoryId){return _categoryRepository.GetCategoryById(categoryId);}}
}
5. 实现编辑Category的方法
  • 创建EditCategoryUseCase.cs,该类只负责传递一个categoryId和cateogry类,编辑Category
namespace UseCases.CategoriesUseCases
{public class EditCategoryUseCase{private readonly ICategoryRepository _categoryRepository;public EditCategoryUseCase(ICategoryRepository categoryRepository){this._categoryRepository = categoryRepository;}public void Excute(int categoryId,Category catogory){_categoryRepository.UpdateCategory(categoryId, catogory);}}
}
6. 实现获取删除Category的方法
  • 创建EditCategoryUseCase.cs,该类只负责通过id删除category
namespace UseCases.CategoriesUseCases
{public class DeleteCategoryUseCase{private readonly ICategoryRepository _categoryRepository;public DeleteCategoryUseCase(ICategoryRepository categoryRepository){this._categoryRepository = categoryRepository;}public void Excute(int categoryId){_categoryRepository.DeleteCategoryById(categoryId);}}
}

5.2.3 创建ProductsUseCases

所有的UseCases只有一个公共的方法Excute()的好处:

  1. 单一职责,只要是usecase就只有Excute的方法
  2. 统一入口点都是Excute(),这样以后使用泛型或者反射都易于调用
  • 从功能出发,如果我们需要一个处理products相关的业务,需要对products数据表有哪些操作
  1. 查询出所有的products, ViewProductsUseCase.cs
  2. 查询单个product的信息,ViewSelectedProductUseCase.cs
  3. 添加单个product,AddProductUseCase.cs
  4. 编辑单个product,EditProductUseCase.cs
  5. 删除单个product,DeleteProductUseCase.cs
  • 可以看出来以上都是基础的增删改查,和CategoriesUseCases 基本一样,下面是products自己独有的方法
1. 创建一个AddProductUseCase
  • 这里,我们先不用考虑程序里有什么接口,有什么功能,我们只需要写
    1. 创建一个Excute函数,在所有的UseCase的公共出口
    2. 函数里面里根据功能,这里是添加一个Products,所以直接调用 _productRepository.AddProduct(product);
    3. 通过构造函数从容器中拿我需要repository

在这里插入图片描述

2. 使用快捷键生成IProductRepository接口
  • 使用快捷键 生成接口,将会自动在原目录下生成一个IProductRepository.cs的文件
    在这里插入图片描述
  • IProductRepository.cs
namespace UseCases.ProductsUseCases
{public interface IProductRepository{}
}
  • 将自动该文件移动到DataStorePluginInterfaces文件夹下
3. 通过快捷键生成接口对应的AddProduct方法
  • 继续使用快捷键,往接口里添加AddProduct方法
    在这里插入图片描述
  • 此时,在IProductRepository接口里,我们的方法已经添加成功
using CoreBusiness;namespace UseCases.ProductsUseCases
{public interface IProductRepository{void AddProduct(Product product);}
}
4. 通过同样的方式,将剩下的几个UseCase完成
5. 通过快捷键将UseCase 提取成为接口
  • 使用快捷件, 将所有的UseCases提成接口

在这里插入图片描述

  • 会在同级目录下生成一个IAddProductUseCase.cs文件
using CoreBusiness;namespace UseCases.ProductsUseCases
{public interface IAddProductUseCase{void Execute(Product product);}
}
  • 并且自动,添加了该接口
    在这里插入图片描述

5.3 创建Plugins

Plugins就是真正实现ICategoryRepository的地方

5.3.1 实现一个内存存储的plugin

  • 实现内存存储

1.在项目的根目录下创建一个Plugins文件夹,除了在vs里创建,还需要到项目的Folder里创建,因为vs创建的文件夹只是一个视图文件夹,真正的文件夹要在folder里创建

在这里插入图片描述
2. 创建一个Plugins.DateStore.InMemory类库,并在类库里创建CategoriesInMemoryRepository.cs,该类库实现了ICategoryRepository的所有功能

 public class CategoriesInMemoryRepository : ICategoryRepository
  1. 将之前我们使用的内存存储和查询的方法,放到该类库内
    在这里插入图片描述
  2. 由于方法的名称一样,这里直接使用即可
    在这里插入图片描述

5.4 使用IOC在Controllers里

5.4.1 将CategoriesUseCases里的实现抽离成为接口

在这里插入图片描述

5.4.2 在CategoriesContollers里使用

  1. 注入IViewCategoriesUseCase
  2. 在程序program入口,注入到容器中
  3. 注入ICategoryRepository数据库的接口

5.4.3 使用相同的方法将Categories相关的usecase抽离成为接口

在这里插入图片描述


http://www.ppmy.cn/news/1554318.html

相关文章

k8s-容器运行时接口分析

1、为了什么需要 CRI &#xff1f; 在 k8s v1.5 之前&#xff0c;Docker 作为第一代的容器运行时&#xff0c; kubelet 通过内嵌其中的 DockerShim 操作 Docker API 来操作容器。在 Kubernetes 1.5 中引入了 CRI&#xff0c;可以解耦了kubelet与容器运行时&#xff0c;该插件接…

qiankun学习记录

什么是微前端 微前端是指存在于浏览器中的微服务&#xff0c;其借鉴了微服务的架构理念&#xff0c;将微服务的概念扩展到了前端。 如果对微服务的概念比较陌生的话&#xff0c;可以简单的理解为微前端就是将一个大型的前端应用拆分成多个模块&#xff0c;每个微前端模块可以…

Linux: glibc: 频繁调用new/delete会不会导致内存的碎片

最近同事问了一个问题:频繁调用new/delete会不会导致内存的碎片。 下面是我想到的一些回答, glibc的内存处理机制,是在释放的时候会自动将小块内存整合成大块内存,为接下来满足大块的需求的可能。而且程序也不是一直占着内存不释放(如果是一直不释放,要考虑是不是内存泄漏…

【Linux】08 -- 重定向命令及管道命令

重定向命令及管道命令 Shell命令或应用程序在执行时&#xff0c;往往需要从输入设备接收一些输入数据&#xff0c;并将处理结果输出到输出设备上。在Linux系统中&#xff0c;这些输入/输出设备都被作为文件来对待。对应输入/输出设备的文件称为I/O文件。 Linux系统定义了3个标准…

Ansible常用操作-ansible模块

1.Ansible介绍 1.1 Ansible简介 &#xff08;1&#xff09;Ansible不需要安装客户端&#xff0c;通过sshd去通信&#xff08;无密钥登陆&#xff09;。 &#xff08;2&#xff09;Ansible无服务器端&#xff0c;使用时直接运行命令。 &#xff08;3&#xff09;Ansible基于…

Linux下进程替换exec系列接口

文章目录 Linux下进程替换1. c库exec函数族一、exec函数族简介二、exec函数族函数原型及参数说明三、exec函数族的工作机制四、注意事项五、示例代码 2. 系统调用execve接口一、execve接口与C库exec函数族的关系二、函数原型三、参数说明四、工作原理五、返回值六、注意事项七、…

方案介绍|CW32L010安全低功耗MCU:驱动高速风筒新力量

吹风机一直以来都是消费者日常生活中的高频刚需产品&#xff0c;而高速风筒更是因为其快速干发、护发养发和低噪音的优势&#xff0c;逐渐成为家庭不可或缺的电器之一。 高速风筒通过采用高速电机和优化的气流设计&#xff0c;能够在短时间内快速吹干头发&#xff0c;同时减少…

【YOLO部署Android安卓手机APP】YOLOv11部署到安卓实时目标检测识别——以火焰烟雾目标检测识别举例(可自定义更换其他目标)

前言:本项目基于YOLOv11部署到手机APP实现对火焰烟雾的检测识别,当然,以此你可以按照本项目开发步骤扩展更换为其他目标进行检测,例如更换为车牌、手势、人脸面部活动、人脸表情、火焰烟雾、行人、口罩、行为、水果、植物、农作物等等部署手机APP进行检测。本文为详细设计/…