我有一个类有一个复杂的构造过程和许多参数。多个客户机共享该类的对象,这些客户机参数的联合用于实例化该类。因此,我有一个工厂类来存储这些需求,检查各种客户机请求的一致性,并实例化该类。在
此外,还有一组通用的使用模型(或参数集),多个客户机将其用于多个工厂。在
例如,考虑一个例子。(注意,实际代码是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张课桌和一块黑板。我认为这最好由非成员函数/装饰器来实现,比如:
^{pr2}$这似乎是“偏好非成员/非朋友对成员”范式的一个很好的例子。在
我正在努力解决的问题是,在一个更大的OO代码框架内,这些类型的非成员函数/装饰器应该在哪里生存,无论是在命名空间方面还是在实际文件方面?在
它们应该存在于工厂的文件/命名空间中吗?它们与工厂有着密切的联系,但它们对一般工厂是有局限性的,不需要用来使用工厂。
它们应该存在于客户机的文件/命名空间中吗?客户机理解这些使用模型,但这将限制多个客户机之间的重用。
如果它们与客户机的公共基类共存(例如,可以想象一个“teacher”类/命名空间,它还将提供非成员函数makeTeacherRoom(),该函数将由MathTeacher和geographytacher继承。
他们是否应该完全住在别的地方,在“utils”文件中?如果是,在哪个命名空间中?
您可能希望在应用程序的单例类中处理非成员函数。工厂可以从程序或其他对象执行。在
C++支持全局函数(非成员函数),但是,对于应用程序使用单个对象,“做这个把戏”。在
另外,由于“教室”对象可以用许多可选参数实例化,所以您可能希望在调用构造函数(python中的init)之后分配它。在
干杯
就我个人而言,我会让他们成为班上的静态成员。在
它们对属于某个静态类的私有方法没有访问权限。这也意味着这些方法并没有与它们所作用的数据分开,如果你把它们放在某个地方的实用程序头中,就会出现这种情况。在
这主要是个人决定。你的大多数选择没有技术上的负面影响。例如:
我通常会创建一个相关命名的util文件(或具有静态方法的类),并将其放在与其所使用的类相同的命名空间中(mutilate的更有用版本)。对于
Education::Teacher
类,可以有一个Education::TeacherUtils
文件或类,其中包含对Teacher
操作的函数。这保持了一个非常明显的命名绑定,但也将util函数放在它们自己的区域中,因此可以根据需要将它们包括在内(在Teacher.cpp
或类似的函数中可以避免这一点)。在类的情况下,您可以将util和基类交为朋友,这偶尔会有所帮助(但很少使用,因为这可能是一种气味)。在我见过一个命名变体},而不是{})。因此,我更喜欢保留
Education::Utils::Teacher
,但是这有点难以翻译成文件(除非你把东西放进utils
目录中),而且还可能导致名称解析的奇怪(在某些上下文中,编译器可能会尝试使用Education::Utils::Teacher
而不是{utils
作为后缀。在相关问题 更多 >
编程相关推荐