反模式 DI anti-patterns
反模式DI anti-patterns一、一、反模式 DI anti-patterns
1. 控制狂 Control freak
在程序设计中,"Control freak
"(控制狂)通常指的是一种反模式,即过度控制和过度管理代码的设计和执行流程。这种情况下,程序员试图通过过度的控制和指令来达到对代码的绝对控制,而忽视了灵活性、可扩展性和可维护性。
控制狂在程序设计中可能表现为以下行为:
-
过度复杂的控制逻辑:设计过于复杂的控制逻辑,使得代码难以理解和维护。
-
过度使用全局状态:滥用全局变量或全局状态,使得代码之间的依赖关系变得混乱和难以追踪。
-
过度依赖条件语句:过多地使用条件语句(如if-else语句),导致代码逻辑分散、冗长和难以扩展。
-
过度使用硬编码:将具体数值、路径或配置直接硬编码到代码中,而不是使用配置文件或参数来实现灵活性。
这些行为会导致代码的可读性、可维护性和可扩展性下降,增加了代码的复杂性和脆弱性。相反,良好的程序设计应该追求简洁、模块化和松耦合的原则,以实现可维护、可扩展和易于理解的代码。
1-1. 示例:
- ...
- private readonly IProductRepository _productRepository;
-
- public ProductService()
- {
- //反模式范例,直接new一个SqlProductRepository,导致紧耦合
- _productRepository = new SqlProductRepository();
- }
- ...
1-2. 工厂模式下的反模式
实体工厂可以解决一些复杂物件建立逻辑封装在工厂中,可以避免写重复的代码。 但是在DI架构下,工厂模式没有带来益处。
- public class ProductRepositoryFactory
- {
- public static IProductRepository CreateProductRepository()
- {
- //工厂模式反模式范例,程序变复杂,只是控制狂换了个位置
- return new SqlProductRepository();
- }
- }
即便将上述代码改为读取外部配置的静态工厂,仍然是对问题换了个地方。ProductServiece
依赖ProductRepositoryFactory
,ProductRepositoryFactory
又依赖于SqlProductRepository
和AzureProductRepository
,因此依赖传递导致ProductServiece
对后两者的依赖。
- public static IProductRepository Create()
- {
- IConfigurationRoot configuration = new ConfigurationBuilder()
- .SetBasePath(Directory.GetCurrentDirectory())
- .AddJsonFile("appsettings.json")
- .Build();
- string repositoryType = configuration["productRepository"];
- switch (repositoryType)
- {
- case "sql": return new SqlProductRepository();
- case "azure": return AzureProductRepository();
- default: throw new InvalidOperationException("...");
- }
- }
IProductRepository
1-3. 构造重载时的控制狂
下面案例中无参构造将SqlProductRepository
作为外部预设,造成业务层对SQL数据层的依赖耦合
- private readonly IProductRepository repository;
- public ProductService()
- : this(new SqlProductRepository())
- {
- }
- public ProductService(IProductRepository repository)
- {
- if (repository == null)
- throw new ArgumentNullException("repository");
-
- this.repository = repository;
- }