【问题标题】:Which is a more maintainable way to construct objects?哪种构造对象更易于维护?
【发布时间】:2013-06-02 03:37:00
【问题描述】:

我正在尝试学习设计模式、最佳实践等。有一个特定的问题总是让我感到困惑。 抽象或 KISS 更重要(保持简单和愚蠢)。 假设我需要构造一个包含多个属性的对象。有两种方式:

1) 实例化对象并将属性传递给构造函数。

$user = new user($user_detail_array); // one line code is enough

这种方法的好处:

  • 代码很小。
  • 非常好的抽象。
  • 短代码很容易管理。

否定:

  • 添加新代码会导致问题,
  • 很难遵循 DRY(不要重复自己)。
  • 违反单一责任规则

2) 实例化对象并单独设置每个属性。

$user = new user();
$user->setName($name);
$user->setEmail($email);
$user->setGender($gender);
so on....

好处:

  • 这很容易理解。
  • 易于更改。
  • 看起来更好。

否定:

  • 这不是很好的抽象。
  • 所有方法都是可见的。
  • 要编写的长代码。试图过度关注 KISS 本身变得很困难。
  • 类之间的交流变得困难。课程太多,无法交流。这么多公共功能。
  • 它将类似于程序代码。

一般来说,更好的方法是什么?如果视情况而定,第一种方法何时比第二种方法更好?为什么?我发现这两种方法都会引起问题。第一种方法使代码过于抽象。第二种方法会使代码太长且难以管理。

【问题讨论】:

    标签: oop design-patterns constructor


    【解决方案1】:

    现实情况是,我认为您的两个示例之间没有太大区别。

    以第一个例子$user = new user($user_detail_array);为例。是的,这似乎更短,但实际上,在这行之前我们通常会看到什么?

    $user_detail_array = {
        "name" => "Bill",
        "email" => "billg@microsoft.com",
        "gender" => "male"
    };
    $user = new user($user_detail_array);
    

    哇,现在看起来和第二种方法没什么区别了……

    $user = new user();
    $user->name = "Bill";
    $user->email = "billg@microsoft.com";
    $user->gender = "male";
    

    我的意思是,user 实体的每个属性都会在程序中的某个位置出现在=>(赋值)旁边。无论是在数组键、构建器对象的属性中,还是直接在实体本身上 - 它们都必须分配一段时间。

    我认为在这种情况下最好的做法是让分配 (=>) 尽可能靠近实体,这样最清楚分配的内容和分配的位置。

    【讨论】:

    • 我根本不懂 PHP,如果我的示例中的语法错误,请致歉。
    • 谢谢,别担心,我能理解。它帮助到我。但我得出结论,设计模式可以帮助我们,但它们不是灵丹妙药。编程仍然很复杂。
    【解决方案2】:

    关于抽象的另一件事是您不需要分别设置姓名、电子邮件和性别。

    您可以简单地将它们抽象到数组中并创建一个新的 setter:

    $user->setUserDetail($userDetailArray);
    

    【讨论】:

      【解决方案3】:

      我认为您只是误解了一些概念。首先,KISS 并不意味着你应该在不使用抽象的情况下编写糟糕的代码。事实上,抽象是帮助程序员编写简单代码的最强大的东西之一。

      您设计程序的方式始终取决于具体情况。如果您正在编写只应该运行一次的脚本,甚至不要考虑抽象。这将是一个矫枉过正。但是,如果您的程序的生命周期很长,请尝试使用抽象并为您的 user 类的客户端提供直观和简单的界面。想象一下,使用user 的代码只想更改它的名称。在您的第一种方式中,他们应该为user 提供整个新数组。在第二种方式中,您只需调用方法setName。而已。

      总结一下:当你设计一个类时,不要考虑编写这段代码的简单性。您应该考虑使用您当前正在编写的类的简单性。

      【讨论】:

        【解决方案4】:
        $userBuilder = new UserBuilder();
        $userBuilder.name = $name;
        // and so on
        $user = $userBuilder -> build();
        

        它是抽象的,不重复任何东西,它添加了另一种模式(Builder)。

        【讨论】:

        • 好的,我正在努力学习它。但这很矛盾,我发现学习设计模式很困难。和设计模式是为了让事情变得简单。
        • 它们的主要目的是为以后和/或其他人制作东西,真的。不是为您编写代码,而是为您或其他维护它的人。
        • 这个构建器对象提供了什么值而不是仅仅在user 实例上设置属性?您是否暗示user 应该是不可变的?
        • @MattDavey,这就是我从 OP 显示的代码中得出的结论。如果不应该,那么 name 等显然是属性。
        • @aaaaaa123456789 是的,我认为我们需要 OP 进一步澄清。如果事实证明他的用户实体是不可变的,我会回来支持你:)
        猜你喜欢
        • 1970-01-01
        • 2011-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多