Ví dụ trong Python không quá khác biệt so với các ví dụ khác. Để thử kịch bản PHP:
class StrategyExample:
def __init__(self, func=None):
if func:
self.execute = func
def execute(self):
print("Original execution")
def executeReplacement1():
print("Strategy 1")
def executeReplacement2():
print("Strategy 2")
if __name__ == "__main__":
strat0 = StrategyExample()
strat1 = StrategyExample(executeReplacement1)
strat2 = StrategyExample(executeReplacement2)
strat0.execute()
strat1.execute()
strat2.execute()
Output:
Original execution
Strategy 1
Strategy 2
Sự khác biệt chính là:
- Bạn không cần phải viết bất kỳ lớp khác hoặc thực hiện bất kỳ giao diện.
- Thay vào đó, bạn có thể chuyển tham chiếu hàm sẽ được ràng buộc với phương pháp bạn muốn.
- Các chức năng vẫn có thể được sử dụng riêng và đối tượng gốc có thể có hành vi mặc định nếu bạn muốn (mẫu
if func == None
có thể được sử dụng cho điều đó).
- Thật vậy, nó gọn gàng và thanh lịch như bình thường với Python. Nhưng bạn mất thông tin; không có giao diện rõ ràng, lập trình viên được giả định là người lớn để biết họ đang làm gì.
Lưu ý rằng có 3 cách để tự động thêm một phương pháp trong Python:
Con đường tôi đã cho các bạn. Nhưng phương pháp sẽ tĩnh, nó sẽ không nhận được đối số "tự".
Sử dụng tên lớp:
StrategyExample.execute = func
Ở đây, tất cả các trường hợp sẽ nhận được func
như phương pháp execute
, và sẽ nhận được self
thông qua như là một cuộc tranh cãi.
Ràng buộc với một trường hợp duy nhất (sử dụng các mô-đun types
):
strat0.execute = types.MethodType(executeReplacement1, strat0)
hoặc với Python 2, lớp của các trường hợp được thay đổi cũng được yêu cầu:
strat0.execute = types.MethodType(executeReplacement1, strat0, StrategyExample)
Điều này sẽ bi nd phương pháp mới cho strat0
và chỉ strat0
, giống như ví dụ đầu tiên. Nhưng start0.execute()
sẽ nhận được self
được chuyển làm đối số.
Nếu bạn cần sử dụng tham chiếu đến cá thể hiện tại trong hàm, thì bạn sẽ kết hợp phương thức đầu tiên và phương thức cuối cùng. Nếu bạn không:
class StrategyExample:
def __init__(self, func=None):
self.name = "Strategy Example 0"
if func:
self.execute = func
def execute(self):
print(self.name)
def executeReplacement1():
print(self.name + " from execute 1")
def executeReplacement2():
print(self.name + " from execute 2")
if __name__ == "__main__":
strat0 = StrategyExample()
strat1 = StrategyExample(executeReplacement1)
strat1.name = "Strategy Example 1"
strat2 = StrategyExample(executeReplacement2)
strat2.name = "Strategy Example 2"
strat0.execute()
strat1.execute()
strat2.execute()
Bạn sẽ nhận được:
Traceback (most recent call last):
File "test.py", line 28, in <module>
strat1.execute()
File "test.py", line 13, in executeReplacement1
print self.name + " from execute 1"
NameError: global name 'self' is not defined
Vì vậy, các mã đúng sẽ là:
import sys
import types
if sys.version_info[0] > 2: # Python 3+
create_bound_method = types.MethodType
else:
def create_bound_method(func, obj):
return types.MethodType(func, obj, obj.__class__)
class StrategyExample:
def __init__(self, func=None):
self.name = "Strategy Example 0"
if func:
self.execute = create_bound_method(func, self)
def execute(self):
print(self.name)
def executeReplacement1(self):
print(self.name + " from execute 1")
def executeReplacement2(self):
print(self.name + " from execute 2")
if __name__ == "__main__":
strat0 = StrategyExample()
strat1 = StrategyExample(executeReplacement1)
strat1.name = "Strategy Example 1"
strat2 = StrategyExample(executeReplacement2)
strat2.name = "Strategy Example 2"
strat0.execute()
strat1.execute()
strat2.execute()
chí này ra kết quả mong đợi:
Strategy Example 0
Strategy Example 1 from execute 1
Strategy Example 2 from execute 2
Tất nhiên, trong trường hợp các chức năng không thể được sử dụng độc lập nữa, nhưng vẫn có thể bị ràng buộc với bất kỳ cá thể nào khác của bất kỳ đối tượng nào, mà không có bất kỳ giới hạn giao diện nào.
Đây là mẫu mẫu, không phải là chiến lược – Twisty