【问题标题】:Best way to refactor two classes with very similar methods?用非常相似的方法重构两个类的最佳方法?
【发布时间】:2014-12-15 23:13:03
【问题描述】:

我有两个独立的类,并且都包含相同的方法名称(启动、验证等)。

但是,两个类之间的方法所期望的参数是不同的。

例如...我有类似的东西:

public static class A
{
    public static void Start(string a, string b) ...implementation inside of it

    public static void Validate (string a, FileInfo b) ...implementation inside of it
}


public static class B
{
     public static void Start (string a) ...implementation inside of it

     public static void Validate(string a, string h FileInfo b, string[] c) ...implementation inside of it
}

有没有办法用设计观点中更好的代码来重构它?这两种方法也共享一些通用代码。

我试图创建一个接口(我必须从两个类中删除静态),但最后它是一团糟,因为我必须在 A 类和 B 类中实现 4 个方法中的每一个,这不是什么我在寻找。

如果我能对此有所了解,那就太好了。我需要一个接口吗?也许和抽象类?还有什么?

【问题讨论】:

  • 要回答这个问题,我们需要更多关于类在语义上应该做什么的信息。也许有一种方法可以使参数相等;也许功能的某些部分可以提取到另一个类中。这取决于。
  • 我同意@valenterry:我不会仅仅根据您提供的信息进行任何重构。从表面上看,这两个类只是通过名称相同但参数不同的方法相关联!这些方法可能彼此无关。它们的任何共同点都是如何实施的问题。我可能会重构实现,但我不会重构公共接口。

标签: c# interface refactoring abstract-class


【解决方案1】:

在这种情况下,我会将 Validate 函数的输入参数分组到一个新类中

public static class Params {
    public string a,
    public FileInfo b
}

然后将这个类扩展为

public static class ExtendedParams extends Params {
    public string h,
    public string[] c
}

那么我原来的A、B类就可以使用同一个接口了

interface iAB {
    public Start(string a, string b)
    public Validate(Params c)
}

每个类都会以不同的方式实现 Start 和 Validate,但 B 类会期望 ExtentedParams 作为输入,因此您必须将其强制转换为 ExtendedParams 才能访问额外的字段。

如果您需要一种更简洁的方法,根据您的对象语义,Params 对象应该公开一个接口,其中包含您要对它们(或它们的数据)执行的操作,并让它们处理逻辑。例如(基于上一个示例):

public static class Params {
    public string a,
    public FileInfo b,
    public void validate()
}

public static class ExtendedParams extends Params {
    public string h,
    public string[] c,
    public void validate()   // implements its own validation
}

最后,这实际上取决于您自己系统中的逻辑,但这将是我要遵循的方向。

【讨论】:

    【解决方案2】:

    IMO 有一种更简单的方法。这两个类都是从静态开始的,而您取消了它,因为您想要基于接口或基于继承的解决方案。更简单的方法是在单个类中重载方法。

    这意味着您可以将这些方法折叠成一个具有多个重载方法的单个静态类。这将使您的重构更简单,还允许您在“统一”类中更轻松地重用公共代码。

    所以,是这样的:

    public static class AB // combined
    {
        public static void Start(string a, string b) ...implementation inside of it
    
        public static void Validate (string a, FileInfo b) ...implementation inside of it
    
        public static void Start (string a) ...implementation inside of it
    
        public static void Validate(string a, string h FileInfo b, string[] c) ...implementation inside of it
    
        private static string SomeCommonFunctionality(string a, string h) ...implementation
    }
    

    【讨论】:

      【解决方案3】:

      使用可选参数。这取决于您的代码在做什么,这是否是一个可行的解决方案。

      public static class B
      {
           public static void Start (string a, string b = string.empty)
           {
                //common code
                if (b != string.empty)
                {
                    var s = SomethingSpecific(string y)
                }
                //common code
           }
           public static void Validate(string a, string h FileInfo b, string[] c = null)
           {
      
           }
      
           private static string SomethingSpecific(string y)
           {
                //Do some custom logic here
           }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-21
        • 2019-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-17
        • 1970-01-01
        • 2021-08-17
        相关资源
        最近更新 更多