-1

我对划分一个类或实例方法并将其移动到自己的类中非常痴迷,很多时候一个简单的“hello world”方法会被划分为许多类。

例如,

class MainProgram
  def hello_world
    puts "hello world"
  end
end

将分为

class SayHello
  def initialize
    @hello = "hello"
  end

  def hello
    @hello
  end
end

class SayWorld
  def initialize
    @world = "world"
  end

  def world
    @world
  end
end

class SayHelloWorld
  def initialize
    @hello = SayHello.new.hello
    @world = SayWorld.new.world
    @hello_world = "#{@hello} #{@world}"
  end

  def hello_world
    @hello_world
  end
end

class MainProgram
  def hello_world
    @hello_world = SayHelloWorld.new.hello_world
    @hello_world
  end
end

有时感觉没有必要。这样做有什么好处吗?

我什么时候停止重构我的代码?有没有重构代码之类的东西?

4

3 回答 3

4

仅当您看到代码重复的代码足够复杂(或包含业务逻辑)时才应启用“重构模式” ,这可能会导致以后进行维护/更新时出现问题;这样它会创建这样的场景,您可能会忘记更新所有原本应该在功能上相同的代码位置,从而导致取决于代码路径的功能行为不一致。

一个常见的规则是,一旦你看到 3 个重复的重要代码,你应该重构它。

重构实现了可重用性,但它与制作可重用的软件组件并不完全相同(我认为这是你的动机)。

您正在做的是过度设计您的软件,并且基本上将您的编程语言原本强大而简洁的语法简化为一种更简单、更脆弱和更少表现力的语言。这是因为您创建了太多抽象层并将基本表达式封装到类中。

您应该问自己一个有用的问题是“将这一系列表达转化为一堂课,我有什么好处?” 例如“我需要跟踪状态吗?”、“多个实例有意义吗?”和“我是获得还是失去表达能力?灵活性?方便性?”。

另一种看待它的方式是重构通常是由DRY(不要重复自己)推动的,请记住,DRY 与想要创建可重用的软件组件并不完全相同。但是,也有YAGNI(You Aint Gonna Need It):除非您在不久的将来需要某个功能,否则您现在可能不需要实现它,只需坚持最基础的版本即可(至少在开始时) )。

不要推测未来的路,想“我想让所有选项留待以后;如果我决定做A,如果我决定做B,是的,是的,我要把这个简单的事情变成一个类让你也这样做fg并且h以防以后我决定我需要它......!”。

因此,这在很大程度上与在您开始编写相关代码之前将您的软件需求和范围保持在相当稳定的最终确定水平有关。知道路停在哪里可以帮助你估计你需要多少燃料,如何正确地调整自己的速度,以及将资源按比例分配到最需要的地方。

此外,如果您不熟悉编程和学习一门语言,即使您不需要,您也更有可能觉得需要在程序中硬塞所有语言功能。当您开始编写更复杂的现实世界程序(远远超出 hello world)时,您将了解何时使用什么。

了解软件反模式是加速此过程的最佳方法之一。你目前正在做一种“货物崇拜编程”的形式

于 2012-09-18T09:44:29.170 回答
1

这一切都取决于什么是不变的,什么是变化的。如果您需要一直打印相同的字符串"Hello World",则不需要所有的复杂性。如果您认为您想偶尔更改一次字符串,但不像每次运行它时那样频繁,那么您可能希望将字符串保持为常量,并引用该常量。如果您希望输出根据用户输入以"Hello world""Hello Mars""Hello Moon"等形式发生变化,那么您可以使该"Hello"部分硬连线,并为不同部分的用户输入设置一个例程。等等

于 2012-09-18T10:07:03.020 回答
1

直观地说,每个人都知道如何编写“Hello world”程序:

puts "Hello world!"

那么为什么要麻烦 OOP 呢?答案是,为了未来。如果你现在只想跟世界打个招呼,并且在你的编程生涯中再也不会这样做,就像正常情况一样,那么只需编写 oneliner。何时停止重构的问题取决于您当前编程工作的预计未来用途。例如,如果您正在编写一个网站,将来应该是多语言的,您将执行以下操作:

class Greeter
  GREETINGS = {
    en: "hello",
    ru: "привет",
    cn: "你好"
  }

  TARGET = {
    en: "world",
    ru: "мир",
    cn: "天地"
  }

  def do_your_grim_business( language )
    puts [ GREETINGS[ language ], TARGET[ language ] ].join( ", " ) + "!"
  end
  alias :act :do_your_grim_business
end

timothy = Greeter.new
timothy.act( :en )

这将使您的思想成长,向光明的未来扩展。但不要过度,因为正如那些犯了错误的人所说,Ruby 是 Play-Doh

于 2012-09-18T10:22:24.203 回答