gpt4 book ai didi

c++ - OO 设计——在哪里放置非成员函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:31:48 25 4
gpt4 key购买 nike

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

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

举个例子。 (请注意,实际代码是 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张课 table 和一 block 黑板。我认为这最好由非成员函数/装饰器提供,例如:

def makeTeacherRoom(factory):
factory.addRequirement("n_desks", 10)
factory.addRequirement("n_boards", 1)
return factory

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

我正在努力解决的问题是,在更大的 OO 代码的框架内,这些类型的非成员函数/装饰器应该存在于何处,无论是在命名空间方面还是在实际文件方面?

  1. 他们应该住在工厂的文件/命名空间中吗?它们与工厂密切相关,但它们是对一般工厂的限制,不需要使用工厂。

  2. 它们应该位于客户的文件/命名空间中吗?客户端了解这些使用模型,但这会限制多个客户端之间的重用。

  3. 他们是否应该使用客户端的公共(public)基类(例如,可以想象一个“教师”类/命名空间,它也将提供非成员函数 makeTeacherRoom(),该函数将由 MathTeacher 继承和地理老师。

  4. 他们应该完全住在其他地方,在“utils”文件中吗?如果是,在哪个命名空间中?

最佳答案

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

  1. 他们可以,因为使用地点不同,但这不是必需的。
  2. 他们可以,因为数据的局部性,但同样......
  3. 他们可以,尽管这个看起来确实会让事情变得有点困惑。制作实用程序类时,您可能不得不最终继承它们,或者将部分制作成虚拟的以便稍后重写,这很快就会变得丑陋。
  4. 这是我个人最喜欢的,或者是它的变体。

我通常会创建一个相关命名的 util 文件(或带有静态方法的类),并将其放在与其使用的类相同的命名空间中(更有用的 mutilate 版本)。对于 Education::Teacher 类,您可以有一个 Education::TeacherUtils 文件或类,其中包含对 Teacher 进行操作的函数。这保留了一个非常明显的命名搭配,但也将 util 函数放在它们自己的区域中,因此它们可以从任何需要它们的地方被包含(在 Teacher.cpp 或类似的文件中会阻止这种情况)。在类的情况下,您可以使 util 类和基类成为 friend ,这偶尔会有帮助(但很少使用,因为它可能有异味)。

我看到了一个命名变体,Education::Utils::Teacher,但这有点难以转换为文件(除非您将内容放入 utils 目录中) 并且还可能导致名称解析异常(在某些情况下,编译器可能会尝试使用 Education::Utils::Teacher 而不是 Education::Teacher 而您没有这样做)不是故意的)。因此,我更喜欢将 utils 作为后缀。

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com