目录模式和方法链模式 12/30 | Python 主题月
写在前面
本文正在参加「Python主题月」,详情查看活动链接
这个月是 Python 活动月,我决定尝试用 Python 来刷这 30 天的每日一题和随机一题。然后如果周末有精力,我想捣鼓捣鼓这个python-patterns
设计模式对我来说更多的是学习而不是我的个人经验总结,所以我很可能理解偏,如果有大佬见到了请及时指出,我之所以选择在掘金来写一些个人的东西是因为这里的文章质量更高,我不希望后来者看到了这些文章被误导。
目录模式
class Catalog:
"""catalog of multiple static methods that are executed depending on an init
parameter
"""
def __init__(self, param: str) -> None:
# dictionary that will be used to determine which static method is
# to be executed but that will be also used to store possible param
# value
self._static_method_choices = {
"param_value_1": self._static_method_1,
"param_value_2": self._static_method_2,
}
# simple test to validate param value
if param in self._static_method_choices.keys():
self.param = param
else:
raise ValueError(f"Invalid Value for Param: {param}")
@staticmethod
def _static_method_1() -> None:
print("executed method 1!")
@staticmethod
def _static_method_2() -> None:
print("executed method 2!")
def main_method(self) -> None:
"""will execute either _static_method_1 or _static_method_2
depending on self.param value
"""
self._static_method_choices[self.param]()
# Alternative implementation for different levels of methods
class CatalogInstance:
"""catalog of multiple methods that are executed depending on an init
parameter
"""
def __init__(self, param: str) -> None:
self.x1 = "x1"
self.x2 = "x2"
# simple test to validate param value
if param in self._instance_method_choices:
self.param = param
else:
raise ValueError(f"Invalid Value for Param: {param}")
def _instance_method_1(self) -> None:
print(f"Value {self.x1}")
def _instance_method_2(self) -> None:
print(f"Value {self.x2}")
_instance_method_choices = {
"param_value_1": _instance_method_1,
"param_value_2": _instance_method_2,
}
def main_method(self) -> None:
"""will execute either _instance_method_1 or _instance_method_2
depending on self.param value
"""
self._instance_method_choices[self.param].__get__(self)()
class CatalogClass:
"""catalog of multiple class methods that are executed depending on an init
parameter
"""
x1 = "x1"
x2 = "x2"
def __init__(self, param: str) -> None:
# simple test to validate param value
if param in self._class_method_choices:
self.param = param
else:
raise ValueError(f"Invalid Value for Param: {param}")
@classmethod
def _class_method_1(cls) -> None:
print(f"Value {cls.x1}")
@classmethod
def _class_method_2(cls) -> None:
print(f"Value {cls.x2}")
_class_method_choices = {
"param_value_1": _class_method_1,
"param_value_2": _class_method_2,
}
def main_method(self):
"""will execute either _class_method_1 or _class_method_2
depending on self.param value
"""
self._class_method_choices[self.param].__get__(None, self.__class__)()
class CatalogStatic:
"""catalog of multiple static methods that are executed depending on an init
parameter
"""
def __init__(self, param: str) -> None:
# simple test to validate param value
if param in self._static_method_choices:
self.param = param
else:
raise ValueError(f"Invalid Value for Param: {param}")
@staticmethod
def _static_method_1() -> None:
print("executed method 1!")
@staticmethod
def _static_method_2() -> None:
print("executed method 2!")
_static_method_choices = {
"param_value_1": _static_method_1,
"param_value_2": _static_method_2,
}
def main_method(self) -> None:
"""will execute either _static_method_1 or _static_method_2
depending on self.param value
"""
self._static_method_choices[self.param].__get__(None, self.__class__)()
def main():
"""
>>> test = Catalog('param_value_2')
>>> test.main_method()
executed method 2!
>>> test = CatalogInstance('param_value_1')
>>> test.main_method()
Value x1
>>> test = CatalogClass('param_value_2')
>>> test.main_method()
Value x2
>>> test = CatalogStatic('param_value_1')
>>> test.main_method()
executed method 1!
"""
if __name__ == "__main__":
import doctest
doctest.testmod()
方法链模式
class Person:
def __init__(self, name, action):
self.name = name
self.action = action
def do_action(self):
print(self.name, self.action.name, end=" ")
return self.action
class Action:
def __init__(self, name):
self.name = name
def amount(self, val):
print(val, end=" ")
return self
def stop(self):
print("then stop")
def main():
"""
>>> move = Action('move')
>>> person = Person('Jack', move)
>>> person.do_action().amount('5m').stop()
Jack move 5m then stop
"""
if __name__ == "__main__":
import doctest
doctest.testmod()
小结
参考文献
- 无