我有一个可以与Oracle或MySQL连接的类。该类初始化为关键字“Oracle”或“MySQL”以及一些其他参数,这些参数是两种数据库类型的标准(打印内容,是否停止异常等)。
当我开始时,根据需要添加if Oracle do A, elif MySQL do B
很容易,但是当我添加仅适用于一种数据库类型的更专业的代码时,这变得很难看。我把这个类拆成了两个,一个用于Oracle,一个用于MySQL,有一些共享函数以避免重复代码。
处理调用这些新类的最Pythonic方法是什么?我是否创建了一个使用相同关键字并返回正确类的包装函数/类?我是否更改了调用旧泛型类的所有代码以调用正确的特定于DB的类?
如果需要,我很乐意模拟一些示例代码,但我认为没有必要。在此先感谢您的帮助!
答案 0 :(得分:4)
我是否创建了一个使用相同关键字的包装函数/类并返回正确的类?
这就是主意。这样的功能称为工厂功能:
def connect_to(db, *args):
if db == "MySQL":
return MySQL(*args)
elif db == "Oracle":
return Oracle(*args)
else:
raise ValueError("unknown database type: %r" % db)
确保两个数据库类具有相同的API。您可以使用duck typing或抽象基类(ABC)来实现这一点;如果在类之间共享功能,或者如果要进行isinstance
检查以确定对象是否代表数据库连接,则后者最有用。
在共享功能的情况下,template method pattern通常会派上用场。
答案 1 :(得分:3)
创建一个工厂类,该类返回基于参数的实现。然后,您可以为两种数据库类型创建一个公共基类,每种类型都有一个实现,让工厂根据参数创建,配置并向用户返回正确的实现。
当两个类的行为非常相似时,这很有效;但是一旦你想使用数据库特定的功能,就会变得很难看,因为你需要像isFeatureXSupported()
(好的方法)或isOracle()
这样的方法(更简单但很糟糕,因为它会移动知道哪个数据库具有哪个功能从帮助器类到应用程序代码)。
或者,您可以为两者实现所有功能,并在不支持时抛出异常。在您的代码中,您可以查找异常以检查此情况。这使得代码更加干净,但现在,您可以在不实际使用它的情况下真正检查功能是否可用。这可能会导致应用程序代码出现问题(例如,当您想要禁用菜单时,或者应用程序可以通过其他方式执行此操作时)。