类设计建议:扩展类和代码重用

时间:2010-02-23 18:54:17

标签: c++ oop class-design

这个问题的要点是扩展一个类,最大限度地减少堵塞 - 将所有内容打包到一个类中,并最大化代码重用。阅读完这个问题后,请随时编辑标题或说明,使其更加简洁。虽然这篇文章看起来很长,但我只是想通过大量的例子来彻底解读。

假设我有一个班级:

class UsedByManyPeople
{
  // ...has many fields
};

顾名思义,这个类被许多开发人员使用。我必须在这个类中添加2个功能:

  1. 将UsedByManyPeople转换为SomeOtherType
  2. 的convert()
  3. 返回字符串
  4. 的getFileName()

    它们都是我部门需要的。


    首次尝试解决方案

    起初我想过简单地向UsedByManyPeople添加两个新方法。因此,该类现在看起来像:

    class UsedByManyPeople
    {
      // ...has many fields
    
      public:
        SomeOtherType const convert() const;
        std::string   const getFileName() const;
    };
    

    但是,这2个功能实际上是特定于我部门的用例,而其他部门甚至没有SomeOtherType的类定义,也不关心getFileName()。

    显然,上述方法不是一个好方法(?)。

    你会如何扩展这门课程?

    我想到的替代方案:


    Subclass UsedByManyPeople并创建我自己的类。

    • 将数据和方法结合在一起

    例如,

    class ExtUsedByManyPeople : public UsedByManyPeople
    {
      public:
        SomeOtherType const convert() const;
        std::string   const getFileName() const;
    };
    

    创建Helper类,每个方法一个(yikes!),并将其实现为静态方法。

    • 从方法中分离数据,单一责任

    例如,

    class UsedByManyPeopleToSomeOtherTypeConverter
    {    
      public:
        static SomeOtherType const convert(UsedByManyPeople const&);
    };
    class UsedByManyPeopleFileName
    {
      public:
        static std::string const getFileName(UsedByManyPeople const&);
    };
    

    创建一个Helper类,其中包含所有方法。

    • 从方法中分离数据,单一类别的责任

    例如,

    class UsedByManyPeopleHelper
    {
      public:
        static SomeOtherType const convert(UsedByManyPeople const&);
        static std::string   const getFileName(UsedByManyPeople const&);
    };
    

4 个答案:

答案 0 :(得分:3)

特别是如果这些方法特定于您的部门使用该类,您应该按照以下方式实现它们:创建一个Helper类,其中包含所有方法。

有几个原因:

  • 单个助手类可以 位于另一个逻辑项目中 结构
  • 如果您的新方法不需要访问类的内部状态,则表达清楚。它提供了更好的封装。 (你用const ref补充,这是一种很好的风格)
  • UsedByManyPeople不应该 要自我转换 进入另一种类型。这违反了 SOLID

答案 1 :(得分:2)

最后一个选项不会影响其他人,并将您的一次性需求隔离到单个类

答案 2 :(得分:1)

您不应更改现有的UsedByManyPeople类。如果您的部门对使用的模式有偏好,那么请遵守您所在部门的风格。否则,为转换创建帮助程序类。如果您在未来看到多次转化,则可能需要为每次转化创建一个类。对于getFileName扩展,您可能希望派生一个类(如果这实际上是一个有用的扩展)或将其添加到您的帮助器。

同样,您所在部门的标准(如果存在)应该为您提供指导。如果您没有标准,现在是时候创建标准了。

答案 3 :(得分:1)

虽然这与使用公共静态方法的类几乎完全相同(至少在使用中),但您可以使用命名空间来封装您需要的例程(如前所述,只有调用可以从公共数据和原始类的方法)。

namespace MyDept
{
    SomeOtherType const convert( UsedByManyPeople const& );
    std::string   const getFileName( UsedByManyPeople const& );
}

提供与调用者非常相似的接口,例如来自类的静态调用,例如

overusedObjectAsSomeOtherType = MyDept::convert( overusedObject );

我想听听在此列表中回答的其他人是否在此方法与绝大多数选择之间存在任何真正的差异。