Design patterns 决策逻辑是生活在对决策起作用的类中还是生活在单独的类中更好?

Design patterns 决策逻辑是生活在对决策起作用的类中还是生活在单独的类中更好?,design-patterns,theory,Design Patterns,Theory,举一个简单的例子:我有一个类,它的任务是在给定路径上创建特定的文件(我们称之为FileCreator)。但是,如果文件在所述路径中不存在,则只需要创建这些文件 FileCreator最好检查路径上是否存在文件,如果不存在则创建它们,还是创建第二个负责检查的类(FileChecker)并让FileCreator纯粹进行创建(不考虑它们是否实际存在) 情景1:决策逻辑取决于决策 class FileCreator def initialize(path) @path = path e

举一个简单的例子:我有一个类,它的任务是在给定路径上创建特定的文件(我们称之为FileCreator)。但是,如果文件在所述路径中不存在,则只需要创建这些文件

FileCreator最好检查路径上是否存在文件,如果不存在则创建它们,还是创建第二个负责检查的类(FileChecker)并让FileCreator纯粹进行创建(不考虑它们是否实际存在)

情景1:决策逻辑取决于决策

class FileCreator
  def initialize(path)
    @path = path
  end

  def create_files
    unless files_exists?(path)
      #create files at path
    end
  end

  def files_exists?(path)
     #check if files exist at path
  end
end

file_creator = FileCreator.new('/foo')
file_creator.create_files
情况2:决策逻辑位于自己的类中

class FileChecker
  def initialize(path)
    @path = path
  end

  def files_exists?(path)
     #check if files exist at path
  end
end

class FileCreator
  def initialize(path)
    @path = path
  end

  def create_files
    #create files at path
  end
end

file_checker = FileChecker.new('/foo')
file_creator = FileCreator.new('/foo')
file_creator.create_files unless file_checker.files_exists?
第一个场景更方便,但我认为第二个场景更灵活(从这个意义上说,我现在确切地知道哪个类负责什么,所以我可以轻松地处理它们)


我对编程非常陌生,因此任何关于这个特定问题的想法或模式的外部引用都会受到欢迎(同时,也不确定这个问题是否正确标记)。

我更倾向于将这两个功能放在同一个类中。OOP是关于在单个对象中结合数据和行为的。在本例中,您的数据是您的路径和文件名,并且您有两个与该数据相关联的行为:检查存在性和创建

考虑到这一点,我认为OOP更喜欢将这个对象称为File,而不是File+某个动词。毕竟,OOP是关于对象建模的,对象的动词是它的方法

我的实现可能类似于:

public class File
{
    private readonly string path;

    public File(string path)
    {
        this.path = path;
    }

    public void Create()
    {
        if (!DoesFileExist())
        {
            // create file.
        }
    }

    private bool DoesFileExist()
    {
        // check if file exists.
    }
}

我更倾向于将这两个功能放在同一个类中。OOP是关于在单个对象中结合数据和行为的。在这种情况下,数据是路径和文件名,您有两种与该数据关联的行为:检查存在性和创建

考虑到这一点,我认为OOP更喜欢将这个对象称为File,而不是File+某个动词。毕竟,OOP是关于对象建模的,对象的动词是它的方法

我的实现可能类似于:

public class File
{
    private readonly string path;

    public File(string path)
    {
        this.path = path;
    }

    public void Create()
    {
        if (!DoesFileExist())
        {
            // create file.
        }
    }

    private bool DoesFileExist()
    {
        // check if file exists.
    }
}

答案是这可能不重要;但是,单个责任类通常更易于重用,特别是在您具有多重继承的情况下。除非有特别的理由把它们绑在一起,否则你最好把它们分开


如果没有其他考虑,我可能会把这个例子作为一个类来编写。然而,一旦它成为一件需要深思熟虑的事情,你也可以把它们分开

答案是这可能无关紧要;但是,单个责任类通常更易于重用,特别是在您具有多重继承的情况下。除非有特别的理由把它们绑在一起,否则你最好把它们分开


如果没有其他考虑,我可能会把这个例子作为一个类来编写。然而,一旦它成为一件需要深思熟虑的事情,你也可以把它们分开

我会尽量保持简单(但不会更简单;-)

在您有意简化的示例中,我将使用一个类,检查功能与创建功能密切相关,因此具有一定程度的内聚性,因此我们可以认为此代码属于同一类

在某些情况下,我会将代码重构为单独的类。在解释一些这样的情况之前,请注意思考过程:我知道我可以根据需要进行重构,实际上我可以在不干扰任何Create功能用户的情况下进行重构;设计有一些内在的灵活性,我们只是在考虑重新安排Create实现的内部结构

重构为两个类的一些可能原因:

  • 我们需要做的检查可能会变得更复杂-例如,检查权限、空间…-我们可能需要检查的运行时选择性,感觉检查类的层次结构可能正在出现,是时候重构了
  • 我们需要在另一个上下文中,在另一个类中重用该检查
  • 检查代码本身就变得复杂了,我们需要重构它的代码以便我们能够理解它,我们专门为检查增加了很多实现函数。此时,我们的Create类变得杂乱无章,是时候进行重构了
  • 随着复杂性的增加,我们看到需要对Check进行单独的测试,因此它已经成为一个一流的类-需要自己记录和控制

  • 我会尽量保持简单(但不简单;-)

    在您有意简化的示例中,我将使用一个类,检查功能与创建功能密切相关,因此具有一定程度的内聚性,因此我们可以认为此代码属于同一类

    在某些情况下,我会将代码重构为单独的类。在解释某些这样的条件之前,请注意思想过程:我知道我知道我需要重构,而且实际上我可以这样做,而不必打扰任何创建功能的用户;设计有一些内在的灵活性,我们只是在考虑重新安排Create实现的内部结构

    重构为两个类的一些可能原因:

  • 我们需要做的检查可能会变得更复杂-例如,检查权限、空间…-我们可能需要检查的运行时选择性,感觉检查类的层次结构可能正在出现,是时候重构了
  • 我们需要在另一个上下文中,在另一个类中重用该检查
  • 检查代码本身就变得复杂了,我们需要重构它的代码以便我们能够理解它,我们会增加很多即时消息
    file_creator = FileCreator.new('path', CreateIfNotExists.new)
    
    file_creator = FileCreator.new('path', CreateAllwaysAndOverride.new)
    
    file_creator = FileCreator.new('path', CreateUntilSpaceLimitIsReached.new('1GB'))