问题
Especially in unittests we use this "design pattern" I call "get class from class level"
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()
...
The method get_response()
gets the class from self
not by importing it. This way a subclass can modify the class and use a different HttpClient
.
What's the name of this (get class from class level) "design pattern"?
Is this a way of "inversion of control" or "dependency injection"?
回答1:
Your code is very similar to Factory method pattern. The only difference is that your variant uses factory class variable instead of factory method.
回答2:
I believe this has the same purpose as just simple polymorphism implemented using Python-specific syntax. Instead of having a virtual method returning a new instances, you have the instance type stored as "an overridable variable" in a class/subclass.
This can be rewritten as a virtual method (sorry I am not fluent in Python so this is just pseudocode)
virtual HttpClient GetClient()
return new FrameworkHttpClient()
then in the subclass, you change the implementation of the method to return a different type:
override HttpClient GetClient()
return new MyHttpClient()
If you want to call this a pattern, I would say it is similar to Strategy GoF pattern. In your particular case, the algorithm being abstracted away is the creation of the particular HttpClient implementation.
And after second thought - as you stated, indeed this can be looked at as an IoC example.
回答3:
I'm not exactly a design pattern 'Guru', but to me it looks a bit like the Template Method Pattern. You are defining the 'skeleton' of the get_response
method in your base class, and leaving one step (defining which class to use) to the subclasses.
If this can be considered the template pattern, it is an example of inversion of control.
回答4:
You want to let the sub classes decide which class to instantiate.
This is what the factory method pattern already offers:
Define an interface for creating an object, but let the classes that implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses. (GoF)
Your solving the same problem by replacing a variable of the parent class. It works but your solution has at least two drawbacks (compared to the classic pattern):
- you introduce a temporal coupling (design smell). Client must call the instructions in the right order. (first initialize the
HttpClient
then invokeget_response
) - your test case is not immutable. Immutable class are simplest than the mutable ones. And in my opinion test should always be simple.
来源:https://stackoverflow.com/questions/27571848/name-of-design-pattern-get-class-from-class-level