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

news2025/2/27 5:33:36

文章目录

  • 项目地址
  • 五、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.coloradmin.cn/o/2258120.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人工智能-自动驾驶领域

目录 引言自动驾驶与人工智能的结合为什么自动驾驶领域适合发表文章博雅智信的自动驾驶辅导服务结语 引言 自动驾驶技术的崛起是当代交通行业的一场革命。通过结合先进的人工智能算法、传感器技术与计算机视觉&#xff0c;自动驾驶不仅推动了技术的进步&#xff0c;也使得未来…

Linux系统操作01|文件目录、常用命令

Linux系统操作教程2天快速入门linux项目搭建_哔哩哔哩_bilibili 目录 一、文件和目录 1、Linux和Windows文件系统的区别 2、主要目录 二、Linux常用命令的基本使用 1、cd&#xff1a;切换文件夹 2、ls&#xff1a;查看当前目录下的内容 3、mkdir&#xff1a;创建文件夹…

VMware Workstation Pro 17 下载 以及 安装 Ubuntu 20.04.6 Ubuntu 启用 root 登录

1、个人免费版本 VMware Workstation Pro 17 下载链接怎么找&#xff1f;直接咕咕 VMware 找到如下链接。链接如下&#xff1a;Workstation 和 Fusion 对个人使用完全免费&#xff0c;企业许可转向订阅 - VMware 中文博客 点进去链接之后你会看到如下&#xff0c;注意安装之后仍…

快速将请求头构建成json结构

1.背景 有时候我们要爬虫(组包)请求一个资源数据,需要构建与原始请求一样的请求头,从浏览器复制过来的请求头,有很多,如果一个一个的配置成json有点慢,那么如何快速构建呢? 今天就使用正则表达式的方式实现 正则表达式实现快速将请求头构建成json结构 将冒号后边的换行符去掉…

Cobaltstrike

Cobaltstrike 資源JFrame 图形用户界面mxGraph数据请求stageless beacon http通信协议 数据加密过程分析Scalar 运行时Aggressor Script Event Queue 客户端通讯登录验证 用户管理外部监听添加監聽Beacon 内容构建 PE解析Payload Generator负载生成Dialog动作选择Listener动作G…

Noise2Noise图像去噪

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

基于SpringBoot和PostGIS的全球城市信息管理实践

目录 前言 一、业务需求介绍 1、功能思维导图 二、业务系统后台实现 1、Model层实现 2、业务层的实现 3、控制层的实现 三、前端管理业务的实现 1、全球城市列表的实现 2、详情页面实现 3、实际城市定位 四、总结 前言 在全球化和信息化时代背景下&#xff0c;城市作…

Cocos Creator 开发微信小游戏分包

作为以后端选手,吭哧吭哧的好不容易用cocos开发了一款小游戏, 上传的时候发现包太大了,主包超过4M; 我不是选小游戏分包了吗? 怎么还超? 分包的方案: 功能裁剪资源压缩主包迁移WASM分离 1. 功能裁剪 项目设置中引擎管理器中 功能裁剪里面有很多个引擎,我们剔除掉没用的引…

计算机网络之NAT、代理服务、内网穿透、内网打洞

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络之NAT、代理服务、内网穿透、内网打洞 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论…

【论文阅读】相似误差订正方法在风电短期风速预报中的应用研究

文章目录 概述&#xff1a;摘要1. 引言2. 相似误差订正算法&#xff08;核心&#xff09;3. 订正实验3.1 相似因子选取3.2 相似样本数试验3.3 时间窗时长实验 4. 订正结果分析4.1 评估指标对比4.2 风速曲线对比4.3 分风速段订正效果评估4.4 风速频率统计 5. 结论与讨论 概述&am…

【Rust 学习笔记】Rust 基础数据类型介绍——数组、向量和切片

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 博客内容主要围绕&#xff1a; 5G/6G协议讲解 高级C语言讲解 Rust语言讲解 文章目录 Rust 基础数据类型介绍——数组、向量和切片一、数组、向量和…

爬虫学习案例3

爬取美女图片 优美图库地址 一页图片 安装依赖库文件 pip install selenium requests beautifulsoup4import time import requests import random from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.chrome.service import Service fr…

ubuntu检测是否已安装nvidia驱动以及产品类型

nvidia-sminvidia-smi 是 NVIDIA 提供的一个命令行工具&#xff0c;用于查看和管理 NVIDIA GPU 的状态。当你运行 nvidia-smi 命令时&#xff0c;它会显示当前系统中所有 NVIDIA GPU 的状态信息&#xff0c;包括 GPU 的使用率、温度、内存使用情况等。 有8个GPU nvcc -V查看c…

使用pyinstaller打包pyqt的程序,运行后提示ModuleNotFoundError: No module named ‘Ui_main‘

环境&#xff1a;windowpython3.9pyqt6 使用pyqt UI编辑器生成了main.ui &#xff0c;main.ui编译成了Ui_main.py main.py 使用当前目录下的Ui_main.py。 打包过程没报错&#xff0c;运行报错。 错误如下: 解决方法&#xff1a;pyinstaller -Fw main.py --paths. 使…

MySQL | 尚硅谷 | 第16章_变量、流程控制与游标

MySQL笔记&#xff1a;第16章_变量、流程控制与游标 文章目录 MySQL笔记&#xff1a;第16章_变量、流程控制与游标第16章_变量、流程控制与游标 1. 变量1.1 系统变量1.1.1 系统变量分类1.1.2 查看系统变量 1.2 用户变量1.2.1 用户变量分类1.2.2 会话用户变量 1.2.3 局部变量1.2…

【环境搭建】Jeecg-Boot v3.5.0 Docker搭建

前言 最近需要复现JeecgBoot的SQL注入漏洞&#xff0c;必须要搭建JeecgBoot v3.5.0这个版本才行&#xff0c;DockerHub没人push这个版本的&#xff0c;相关博客也比较少&#xff0c;所以自己来搭建&#xff0c;记录一下过程。 前置环境 Ubuntu 20.04Docker version 27.3.1do…

Certimate自动化SSL证书部署至IIS服务器

前言&#xff1a;笔者上一篇内容已经部署好了Certimate开源系统&#xff0c;于是开始搭建部署至Linux和Windows服务器&#xff0c;Linux服务器十分的顺利&#xff0c;申请证书-部署证书很快的完成了&#xff0c;但是部署至Windows Server的IIS服务时&#xff0c;遇到一些阻碍&a…

【学一点儿前端】本地或jenkins打包报错:getaddrinfo ENOTFOUND registry.nlark.com

问题 今天jenkins打包一个项目&#xff0c;发现报错了 error An unexpected error occurred: “https://registry.nlark.com/xxxxxxxxxx.tgz: getaddrinfo ENOTFOUND registry.nlark.com”. 先写解决方案 把yarn.lock文件里面的registry.nlark.com替换为registry.npmmirror.…

Linux:软硬链接

目录 一、概念 软链接 硬链接 二、原理 硬链接 软链接 三、使用场景 硬链接 软链接 一、概念 软链接 在当前目录下&#xff0c;有一个普通文件a.txt。 ln -s a.txt a_soft.link结论&#xff1a; 软链接是一个文件。 观察inode_id&#xff0c;发现软链接有着独立…

Java 实现给pdf文件指定位置盖章功能

Java 实现给pdf文件指定位置盖章功能 开发中遇到一个需求, 需要给用户上传的的pdf文件, 指定位置上盖公章的功能, 经过调研和对比, 最终确定实现思路. 这里是使用pdf文件中的关键字进行章子的定位, 之所以这样考虑是因为如果直接写死坐标的话, 可能会出现因pdf大小, 缩放, 盖章…