我有一类具有许多参数的复杂构造过程。多个客户端共享该类的对象,并且使用这些客户端参数的并集来实例化该类。因此,我有一个工厂类来存储这些要求,检查各种客户请求的一致性,并实例化该类。

此外,还有一组通用的使用模型(或参数集),多个客户将其用于多个工厂。

例如,考虑一个例子。 (请注意,实际的代码是C++,但是我的经验是在Python中使用的,所以我将在Python中使用伪代码。是的,我知道此示例实际上不能按原样工作。)

class Classroom:
    def __init__(self, room_size=None, n_desks=None, n_boards=None,
                       n_books=None, has_globe=False, ... ):
        ...

class ClassroomFactory:
    def __init__(self):
        self._requirements = dict()

    def addRequirement(self, name, value):
        if name.startswith("n_"):
            self._requirements[name] = max(value, self._requirements.get(name, 0))
        ...

    def createClassroom(self):
        return Classroom(**self._requirements)


# instantiate the factory
factory = ClassroomFactory()

# "client 1" is a geography teaacher
factory.addRequirement("n_desks", 10)
factory.addRequirement("n_boards", 1)
factory.addRequirement("has_globe", True)

# "client 2" is a math teacher
factory.addRequirement("n_desks", 10)
factory.addRequirement("n_boards", 1)

# "client 3" is a after-school day-care
factory.addRequirement("room_size",  (20,20))
factory.addRequirement("has_carpet", True)

room = factory.createClassroom()

常见的使用模式是作为一名老师,我们需要10张书桌和一块木板。我认为最好由非成员函数/装饰器来实现,例如:
def makeTeacherRoom(factory):
    factory.addRequirement("n_desks", 10)
    factory.addRequirement("n_boards", 1)
    return factory

这似乎是“首选非成员/非 friend 而不是成员”范例的一个很好的例子。

我正在努力的事情是,在更大的OO代码框架内,无论是在 namespace 还是在实际文件方面,这些类型的非成员函数/装饰器都应该放在哪里?
  • 他们应该住在工厂的文件/命名空间中吗?它们与工厂密切相关,但是它们对一般工厂有限制,不需要使用工厂。
  • 它们应该存在于客户端的文件/命名空间中吗?客户了解这些使用模型,但这会限制多个客户之间的重用。
  • 如果他们使用客户端的通用基类(例如,可以想象一个“教师”类/命名空间,它也将提供非成员函数makeTeacherRoom(),该函数将由MathTeacher和GeographyTeacher继承。
  • 它们是否应该完全放在“utils”文件中的其他地方?如果是这样,在哪个 namespace 中?
  • 最佳答案

    这主要是个人决定。您的大多数选择没有技术上的负面影响。例如:

  • 由于使用的局部性,它们可以,但是不是必需的。
  • 由于数据的局部性,它们可以,但是再次...
  • 他们可以,尽管看起来确实可以使事情变得更困惑。制作实用工具类时,您可能最终不得不继承它们,或者使部件成为虚拟部件以供以后覆盖,这很快就会变得很丑陋。
  • 这是我个人的最爱,或者这的一个变体。

  • 我通常制作一个相关命名的util文件(或带有静态方法的类),并将其放在与其使用的类相同的 namespace 中(mutilate的更有用的版本)。对于Education::Teacher类,您可以拥有一个Education::TeacherUtils文件或一个包含对Teacher进行操作的函数的类。这样可以保持很明显的命名关系,但也可以将util函数放在自己的区域中,这样就可以根据需要将它们包括在内(通过Teacher.cpp或类似方法可以防止这种情况)。对于类,您可以将util类和基类作为 friend ,这有时会有所帮助(但很少使用,因为它可能有异味)。

    我已经看到了一个命名变体Education::Utils::Teacher,但是将其转换为文件有些困难(除非您将内容放到utils dir中),而且还会导致名称解析奇怪(在某些情况下,编译器可能会尝试使用Education::Utils::Teacher而不是Education::Teacher当你不是故意的时候。因此,我更喜欢保留utils作为后缀。

    关于c++ - OO设计-放置非成员函数的位置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11213140/

    10-08 22:02