Hello工程界人士, 我的团队正在努力重构一些目前处于非常糟糕状态的代码,即代码库中的数据库调用,如下所示:
public class MyController{
public void SomeRoute(int id){
ClassA a = ClassA.Read(id); // Static method that accesses db
...
}
}
我们试图删除这些直接数据库引用有很多原因,其中最重要的是几乎不可能获得任何测试工具(我们的项目此时几乎没有单元测试)。
为此,我一直在创建一些存储库,每个数据库表一个(如果重要的话,使用Dapper micro-ORM)。作为一个例子,我们有这个复杂的类结构(只是一个例子,不注意名称或类型,因为它们不重要):
public class ClassA {
private List<ClassB> classBList;
private List<ClassC> classCList;
private List<ClassD> classDList;
}
public class ClassD {
private List<ClassE> classEList;
private List<ClassF> classFList;
private List<ClassG> classGList;
}
此时,每个类(A-G)都有自己的数据库表。我一直在为每个类创建一个存储库,即ClassARepository:IClassARepository等。
现在,我的控制器(或任何处理ClassA的类)最初都将所有这些repos注入其中:
public class MyController {
public MyController (IClassARepository repoA, IClassBRepository repoB, ...) {
}
}
我确信你正在思考,正如我所做的那样,许多构造函数args是代码味道,并且我的控制器不是实现业务逻辑以保存所有这些数据的地方。所以,我重构了。
将ClassA持久存储到数据库中有相当多的业务逻辑。首先,它需要自己写。然后,它需要编写ClassB,ClassC和ClassD的列表。接下来,ClassD需要编写其子类,类E-G。最后,它需要删除数据库中存在但在内存中ClassA中不存在的任何项目,即删除了ClassB列表中的项目或删除了ClassF列表中的项目。
我的服务最初看起来像这样:
public class ClassAService : IClassAService {
public ClassAService (ClassARepository repoA, ClassBRepository repoB, ...) {
}
}
但正如你所看到的,我仍然拥有相同数量的依赖项,我只是将它们移到了另一个类。当然,我现在只能在我的控制器中注入一个依赖项:public MyController (IClassAService service)
。
我的下一个想法(以及我目前被困'的地方)是ClassD应该负责编写自己的孩子,所以我也为此创建了一个服务。然后我的ClassAService成为:
public class ClassAService : IClassAService {
public ClassAService (ClassARepository repoA, ClassBRepository repoB, ClassCRepository repoC, ClassDService serviceD) {
}
// Write ClassA along with all its children if writeChildren is true
// and remove (prune) any children that aren't in the lists
public ClassA Write(ClassA classA, bool writeChildren, bool pruneChildren, string username) {
using (var scope = new TransactionScope()) {
// Business logic for coordinating all the different updates/deletes, i.e.
repoA.Write(classA, username);
repoB.Write(classA.ClassBList, username);
repoC.Write(classA.ClassCList, username);
serviceD.Write(classA.ClassDList, writeChildren, pruneChildren, username);
...
}
}
}
对此仍有些不妥,但我不确定是什么。例如,如果ClassA有5个孩子而不是3个孩子,那该怎么办?还是15?
我期待社区了解您对此类问题的体验,并希望听到您对此方法的看法。
感谢您阅读,我期待您的回复!