设计模式的名称:从类级别获取类

时间:2014-12-19 18:27:44

标签: python inheritance design-patterns dependency-injection inversion-of-control

特别是在单元测试中,我们使用这种"设计模式"我打电话给#34;从班级获得课程"

framworktest.py:

class FrameWorkHttpClient(object):
    ....

class FrameWorkTestCase(unittest.TestCase):

    # Subclass can control the class which gets used in get_response()
    HttpClient=FrameWorkHttpClient  

    def get_response(self, url):
        client=self.HttpClient()
        return client.get(url)

mytest.py:

class MyHttpClient(FrameWorkHttpClient):
    ....

class MyTestCase(FrameWorkTestCase):
    HttpClient=MyHttpClient

    def test_something(self):
        response=self.get_response()
        ...

方法get_response()self获取类,而不是通过导入它。这样,子类可以修改类并使用不同的HttpClient

这是什么(从班级获得课程)"设计模式"?

这是"控制反转的方式"或者"依赖注入"?

4 个答案:

答案 0 :(得分:5)

您的代码与Factory method pattern非常相似。唯一的区别是您的变体使用工厂类变量而不是工厂方法。

答案 1 :(得分:4)

我认为这与使用Python特定语法实现的简单多态相同。您没有让虚拟方法返回新实例,而是将实例类型存储为"一个可覆盖的变量"在类/子类中。

这可以重写为虚拟方法(抱歉,我不熟悉Python,所以这只是伪代码)

virtual HttpClient GetClient()
  return new FrameworkHttpClient()

然后在子类中,您更改方法的实现以返回不同的类型:

override HttpClient GetClient()
  return new MyHttpClient()

如果您想将此称为模式,我会说它与Strategy GoF pattern类似。在您的特定情况下,抽象出来的算法是创建特定的HttpClient实现。

经过第二次思考 - 正如你所说的那样,这确实可以看作是一个IoC的例子。

答案 2 :(得分:1)

我并不完全是一种设计模式' Guru',但对我而言,它看起来像模板方法模式一样 bit 。你正在定义骨架'您的基类中的get_response方法,并将一个步骤(定义要使用的类)留给子类。

如果这可以被认为是模板模式,那么它就是控制反转的一个例子。

答案 3 :(得分:1)

您希望让子类决定实例化哪个类。

这是factory method pattern已经提供的内容:

  

定义用于创建对象的接口,但让实现接口的类决定实例化哪个类。 Factory方法允许类将实例化延迟到子类。 (GOF)

您通过替换父类的变量来解决相同的问题。 它有效但你的解决方案至少有两个缺点(与经典模式相比):

  1. 你引入了时间耦合(设计气味)。客户必须按正确的顺序调用说明。 (首先初始化HttpClient然后调用get_response
  2. 您的测试用例不是一成不变的。不可变类比可变类最简单。在我看来,测试应该总是很简单。