这是重用/共享方法的好方法吗?

发布于 2024-12-03 10:42:49 字数 533 浏览 2 评论 0原文

我遇到了这段代码,其中 3 个控制器正在使用方法调用,例如 ClassA.search(a, b, flag)。这是该方法的简化版本:

public List<Result> search(Object a, Object b, boolean flag) {
   //do some code logic here, common to the 3 controllers
   //at the middle there is:
   if (flag) {
      //code that affects 2 Controllers
   } else {
      //code affects only 1
   }
   //some more common code
   //some more code with the flag if else
}

这是一个好主意吗,因为代码被重用了?或者是否有更好的方法仍然能够重用代码,但不为方法调用者(客户端)代码自定义引入此标志(例如可能将其拆分为 3 个不同的方法,但仍然能够声明通用代码重构方法)?

I encountered this code wherein a method call, for example ClassA.search(a, b, flag) is being used by 3 Controllers. This is a simplified version of the method:

public List<Result> search(Object a, Object b, boolean flag) {
   //do some code logic here, common to the 3 controllers
   //at the middle there is:
   if (flag) {
      //code that affects 2 Controllers
   } else {
      //code affects only 1
   }
   //some more common code
   //some more code with the flag if else
}

Is this a good idea because code is reused? Or is there a better way to still be able to make code reuse but not introduce this flag for method caller (client) code customization (like maybe split it to 3 different methods but still be able to declare a common code refactored method)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓝颜夕 2024-12-10 10:42:49

首先,用函数提取注释行:

public void search(Object a, Object b, boolean flag)
{
    commonToThree();
    if (flag)
    {
        affectTwoControllers();
    }
    else
    {
        affectsOnlyOne();
    }
    alsoCommon();
}

现在去掉 flag 布尔参数,这是一种代码味道:

public void searchWithTrueFlag(Object a, Object b) {
    commonToThree();
    affectTwoControllers();
    alsoCommon();
}

public void searchWithFalseFlag(Object a, Object b) {
    commonToThree();
    affectsOnlyOne();
    alsoCommon();
}

First, extract commented lines with functions:

public void search(Object a, Object b, boolean flag)
{
    commonToThree();
    if (flag)
    {
        affectTwoControllers();
    }
    else
    {
        affectsOnlyOne();
    }
    alsoCommon();
}

Now get rid of flag boolean argument, which is a code smell:

public void searchWithTrueFlag(Object a, Object b) {
    commonToThree();
    affectTwoControllers();
    alsoCommon();
}

public void searchWithFalseFlag(Object a, Object b) {
    commonToThree();
    affectsOnlyOne();
    alsoCommon();
}
浪荡不羁 2024-12-10 10:42:49

这很好,但不是很好。一个布尔值是有意义的,但如果你开始添加更多的布尔值,你就不会朝着正确的方向前进。

这并不总是可能的,但通常会产生更好的代码:

functionOne:
  sharedCodeOne()
  specificCode
  sharedCodeTwo()

functionTwo:
  sharedCodeOne()
  specificCode
  sharedCodeTwo()

一如既往,很难做出概括性的声明:这显然并不总是可能/实用的。

It is good but not great. One boolean makes sense, but if you start adding more of them you're not going into the right direction.

It's not always possible, but generally yields better code to do:

functionOne:
  sharedCodeOne()
  specificCode
  sharedCodeTwo()

functionTwo:
  sharedCodeOne()
  specificCode
  sharedCodeTwo()

As always, it's hard to make generalized claims: this is obviously not always possible/practical.

回眸一笑 2024-12-10 10:42:49

这是一种相对简单的方法。有一些替代方案,但它们可能更复杂。 (例如传递访问者或调用控制器的方法来说明该控制器要执行的操作)

如果您在代码的三个部分之间共享局部变量并且必须使用字段,则此方法是最好的。

It is a relatively simple way to do it. There are alternatives but they are likely to be more complex. (Such as passing a visitor or calling a method of the controller to say what to do for that controller)

This approach is best if you share local variables between the three sections of code and you would have to use fields instead.

梦醒时光 2024-12-10 10:42:49

我会采取不同的方法尝试以一般方式回答这个问题:

主要目标应该是干净代码。这具体是什么,当然要看具体情况。但可以肯定的是,在多个地方复制粘贴代码是不好的,因为如果必须更改,这需要更改多个位置 - 同样,尝试在多个部分使用的地方提取公共部分也是不好的他们在所有情况下。

总是想象有人必须阅读您的代码(或者您自己必须在几周后执行此操作)并且必须尽快了解那里发生了什么。因此,这取决于特殊情况,是复制一些行还是用通用方法提取它们更好。

标志本身并不是坏事,但它并不是真正应该在 java 方法中过度使用的东西。通常,这种情况可以通过重载一个方法并在另一个方法中使用一个方法来很好地解决,这样常见的情况在一个方法中完成,特殊的添加在另一个方法中完成。或者,您可以拥有多个子方法,并通过对它们的多次调用来组成您的方法,但这仅在您不需要传递太多参数时才有意义。

我可以给你一条规则(完全主观,但基于从许多项目中吸取的经验教训):优先采用通用方法的具体实现。它们可能会产生更多的代码,并且可能显得不那么聪明,但它们更容易理解、扩展和调试。

I'd take a different approach trying to answer this question in a general way:

The main goal should be clean code. What exactly this is, of course depends on the specific case. But for sure, it's bad to have copy-and-pasted code in several places, since this requires to change several places if it has to be changes - as well, it's bad to try to extract common parts whereever more than one part is using them in all circumstances.

Always imagine someone having to read your code (or yourself having to do this a few weeks from now) and having to understand as fast as possible what's going on there. So, it depends on the special case, if it's better to copy some lines or to extract them in a common method.

A flag is not per se bad, but it's not really something which should be overly used in java methods. Often such a situation can be solved nicely by overloading a method and using one in the other, so that the common case is done in one and the special addition in the other. Alternatively, you can have several sub-methods and compose your method with several calls to them, but this only makes sense, if you don't need to pass too many parameters.

One rule (completely subjective, but based on the lessons-learned from many projects) I can give you: Favor concrete implementations ober generic approaches. They may result in more code and may appear less clever, but they are much easier to understand, extend and debug.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文