这是反模式吗?

aiq*_*ita 1 c# oop design-patterns anti-patterns solid-principles

目前,我经常遇到遵循以下代码演示的模式的代码。这是一种策略模式。

我不喜欢这个,感觉有点臭。它打破了实际的策略模式,额外的间接性令人困惑。此外,它通常会导致类似于示例中的方法,因为派生类中方法的用途与基类中的方法非常相似。另一方面,我无法用手指指向问题核心。

只有我一个人觉得这很可疑吗?如果没有,这段代码会导致什么问题,特别是在 SOLID 原则方面?

namespace MyTest
{
    abstract class Base
    {
        public void DoSomething()
        {
            var param = Prepare();
            DoItReally(param);
        }

        private string Prepare()
        {
            return "Hallo Welt";
        }

        protected abstract void DoItReally(string param);
    }

    class DerivedOne : Base
    {
        protected override void DoItReally(string param)
        {
            Console.WriteLine(param);
        }
    }

    class DerivedTwo : Base
    {
        protected override void DoItReally(string param)
        {
            Console.WriteLine(param.ToUpper());
        }
    }
    
    static class Program
    {
        public static void Main(string[] args)
        {
            Base strategy = new DerivedOne();
            strategy.DoSomething();
            
            strategy = new DerivedTwo();
            strategy.DoSomething();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Fla*_*ter 5

如果将代码分成两个组成部分,您应该会看到它们都非常好。

1. 将一些逻辑抽象为私有方法

public void DoSomething()
{
    var param = Prepare();
    DoItReally(param);
}

private string Prepare()
{
    return "Hallo Welt";
}
Run Code Online (Sandbox Code Playgroud)

鉴于两种方法的方法体都是固定的,而且在这种情况下非常短,我们可以争论这里不需要私有方法。但这只是一个示例,如果您的初始化逻辑变得更加复杂(例如,复杂的数据查询和计算),则需要将其抽象为私有方法。

2. 实现抽象基方法的子类

这正是abstract作为关键字存在的原因。

您的基类知道如何获取数据,但由于有多种处理此数据的方法,因此存在子类,每个子类都定义了这些选项之一。您已经最大限度地提高了基类的可重用性,唯一不可重用的是每个子类的自定义处理逻辑。


我认为您对标记模式和反模式的关注远远超过了实际生产力。

干净的代码不是来自寻找反模式的追求。干净的代码来自于理解你的需求,意识到代码不适合你的目的或有不需要的副作用,然后重构代码以保持它的好处,同时失去或最小化它的缺点。

到目前为止,您还没有显示代码本身有任何问题,也没有显示它可能会导致不必要的副作用的原因。你的问题本质上是疑病症,你过于急切地寻找问题,而不是简单地试图解决一个具体影响你的问题。