我在决定构建某个班级的最佳方法时遇到了一些麻烦。该类将采用一些字符串作为设置,方法将根据设置创建不同类型的图表....
例如,。可以像这样调用......
c = ChartEngine(type='line', labels='foo bar', data='1, 2', data2='3, 4')
chart = c.make_chart()
IDK如果最好将其构造为一个类,或者只是一个将调用同一模块中其他函数的函数... IDK如果我应该将逻辑放在将设置为__init__
的{{1}}函数中调用make_chart
函数或者还有其他方法。
def __init__(*settings*):
self.type = type
self.labels = labels
self.data = data
....
make_chart(self.type, self.labels, self.data):
if self.type == "line":
line_chart(settings)
elif self.type == "bar":
bar_chart(settings)
...
你会如何构建这样的类?
答案 0 :(得分:3)
使用测试作为设计工具。为您想要的一个简单的最小功能编写测试。让它失败,然后编写使其通过所需的最小代码。然后使用其他功能编写其他测试,让它失败,依此类推。使用此开发周期(TDD),您可以从用户的角度进行设计,并对您的实现进行适当的封装和抽象。您可能想了解pytest模块。
乍一看,我会说你计划的课程会对太多不同的事情了解太多。阅读有关SRP和其他SOLID原则的信息,以帮助您了解此事。最重要的是,只执行你现在需要的东西,仅此而已。
最后,ChartEngine
看起来像抽象工厂模式的用例,使用优雅的代码很难实现。从最简单的用例开始,并尽早重构。
答案 1 :(得分:2)
这是一个设计问题。根据问题的本质,您可以使用许多主观方法。你最喜欢设计你的程序,使你的源通常解耦,导致未来的变化是微不足道的。但是 over-engineering 是一件事,所以要考虑到手头的要求。各种方法可以产生某些益处。以下是一个示例方法。
您可以拥有一个名为ChartEngine
的主控制类(,如您所提到的),可以通过Chart
子类调度各种图表。然后,您可以实现一个名为Chart
的基类,该基类充当各种变体的超类。在我看来,你的程序的性质比继承更适合继承(再次,可以使用许多不同的方法)。
class Chart(object):
def __init__(self):
pass
def draw(self):
pass
...
然后通过继承Chart
扩展/覆盖基类的功能。然后,您可以实现类似Line
类的内容,例如:
class Line(Chart):
pass
class Bar(Chart):
pass
对于ChartEngine
,您可以让类具有与MVC Web应用程序中的路径类似的各种图形类型的调度方法。一种方法可能是使用字典来跟踪各种图形及其相关的调度方法。
class ChartEngine(object):
type_to_dispatch = {"bar" : dispatch_bar, "line" : dispatch_line}
def __init__(self, type, labels, data):
self.type = type
self.labels = labels
self.data = data
...
def make_chart(self):
type_to_dispatch[self.type]()
def dispatch_line(self):
pass
def dispatch_bar(self):
pass