首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >“基类参数并不总是被使用”代码气味

“基类参数并不总是被使用”代码气味
EN

Stack Overflow用户
提问于 2011-10-17 18:41:32
回答 3查看 174关注 0票数 0

假设你有这样的代码:

代码语言:javascript
运行
复制
public Base
{
   abstract void Register();
}

public Registrator1: Base
{
   override void Register()
   {
      //uses the current state of the object to populate the UI captions
   }
}

public Registrator2: Base
{
   override void Register()
   {
      //uses the current state of the object to populate the UI captions
   }
}

但是,当您收到一个新的业务规则,要求您编写Registrator3,它实际上是基于某个参数注册的,并且您将代码库更改为下一个:

代码语言:javascript
运行
复制
public Base
{
   abstract void Register(externalParam);
}

public Registrator1: Base
{
   override void Register(externalParam)
   {
      //uses the current state of the object to populate theUI
   }
}

public Registrator2: Base
{
   override void Register(externalParam)
   {
      //uses the current state of the object to populate the UI
   }
}

public Registrator3: Base
{
   override void Register(externalParam)
   {
     //uses a DDD - service passed in the params to populate the UI
   }
}

但是Registrator1和Registrator2不需要这个参数,代码就会变得很难闻。重写这段代码的方法有哪些?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-17 19:31:29

您可以在这里使用对象作为参数;这通常用于参数数量随所使用的调用而变化的场景。

代码语言:javascript
运行
复制
struct RegistrationInfo
{
    public static readonly RegistrationInfo Empty = new RegistrationInfo();
    public string Username;
    public string CustomerName;
    public string Validity; 
}

abstract class Base
{
    public abstract void Register(RegistrationInfo info);
    // If you want to retain the paramaterless call:
    public void Register()
    {
         Register(RegistrationInfo.Empty);
    }
}

class Registrar1 : Base
{
    public override void Register(RegistrationInfo info)
    {
        if (info.Username == null) throw new ArgumentNullException("info.Username");
    }
}

class Registrar2 : Base
{
    public override void Register(RegistrationInfo info)
    {
        if (info.CustomerName == null) throw new ArgumentNullException("info.CustomerName");
    }
}

这样做的好处是,您不需要在每次添加参数时都更改方法参数(这会破坏接口)。用法也变得有些自文档化了:

代码语言:javascript
运行
复制
var r = new Registrar1();
r.Register(new RegistrationInfo(){ Username = "JimJoe" });
r.Register(RegistrationInfo.Empty);

对于这种类型的代码气味,它就像空气清新剂,但它仍然很难闻;您可以让它闻起来更好。

最后,您可以通过将调用站点设置为params参数(这只有少量开销)来使其更整洁;说实话,它更难闻,因为它是一种语言黑客。最后,您可以使用泛型对其进行改进:

代码语言:javascript
运行
复制
class RegistrationInfo
{

}

class RegistrationInfo1 : RegistrationInfo
{
    public string Arg;
}

class RegistrationInfo2 : RegistrationInfo
{
    public int Arg;
}

interface IBase<in TRegistration>
    where TRegistration : RegistrationInfo
{
    void Register(TRegistration registration);
}

class Base : IBase<RegistrationInfo>
{
    public void Register(RegistrationInfo registration)
    {

    }
}

class Registrar1 : IBase<RegistrationInfo1>
{
    public void Register(RegistrationInfo1 arg)
    {
    }
}

class Registrar2 : IBase<RegistrationInfo2>
{
    public void Register(RegistrationInfo2 arg)
    {
    }
}
票数 2
EN

Stack Overflow用户

发布于 2011-10-17 18:55:57

在Registrator3中不能包含externalParam的逻辑吗?换句话说,Registrator3使用参数,然后调用未修改的无参数base?

这在很大程度上取决于逻辑的归属。如果它是基类的固有属性,则将其放在基类中,然后重载Register()函数或为参数提供默认值,这样子类就不需要提供它。

票数 0
EN

Stack Overflow用户

发布于 2011-10-17 19:15:39

假设您想要重用基类中的注册逻辑,您可以按如下方式更新代码:

代码语言:javascript
运行
复制
public class Base
{
   public virtual void Register(object externalParam)
   {
       // base registration logic goes here
   }
}

public class Registrator1: Base
{
   public override void Register(object externalParam)
   {
       base.Register(null);
       // custom registration logic goes here
   }
}

public class Registrator2: Base
{
   public override void Register(object externalParam)
   {
       base.Register(null);
       // custom registration logic goes here
   }
}

public class Registrator3: Base
{
   public override void Register(object externalParam)
   {
       base.Register(externalParam);
       // custom registration logic goes here
   }
}

HTH,

Cosmin

编辑:更新要编译的代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7792567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档