2016-05-18 10 views
6

Rozumiem, że ponieważ Python ma funkcje pierwszej klasy, używanie wzorca strategii jest zwykle kwestią przekazania funkcji jako argumentu, a nie wymagać od zajęć. Ale co, jeśli "strategie" nie są pojedynczymi funkcjami, ale raczej grupy powiązanych funkcji, które logicznie należy wybrać jako zestaw?Wzór strategii w Pythonie, gdy "strategia" składa się z więcej niż jednej funkcji

jak tutaj jest trywialne i wymyślony przykład:

class HexFormatter(object): 
    """Base class for strategies to format hexadecimal numbers.""" 
    pass 

class Motorola(HexFormatter): 
    """Format Motorola style (e.g. $1234)""" 
    @staticmethod 
    def formatbyte(n): 
    return "$%02X" % n 

    @staticmethod 
    def formatword(n): 
    return "$%04X" % n 

class Intel(HexFormatter): 
    """Format Intel-style (e.g. 1234h)""" 
    @staticmethod 
    def formatbyte(n): 
    return "%02Xh" % n 

    @staticmethod 
    def formatword(n): 
    return "%04Xh" % n 

Pomysł jest wybrać strategię i masz funkcję bajtów formatowania i funkcji do formatowania słów jako zestaw, a nie konieczności określenia indywidualnie. Ten przykład jest podobny do tego, jak zrobiłbyś to w języku takim jak C++ (z wyjątkiem tego, że metody nie byłyby statyczne, ponieważ nie możesz mieć wirtualnych metod statycznych w C++) i to nie jest tak, że nie działa w Pythonie. Ale wiąże się to z definicją grupy "klas", które mają tylko statyczne metody i nie mają być tworzone, co wydaje się nie-Pythoniczne.

Czy jest to bardziej idiomatyczny sposób na to w Pythonie?

+0

Czy strategią musi być pojedynczy obiekt? Jeśli nie, możesz przekazać wiele funkcji, np. za pomocą argumentów słów kluczowych, lub może przekazać krotkę lub nazwaną krotką funkcji. –

Odpowiedz

4

Jedną z opcji Znalazłem całkiem miło, gdy masz wiele funkcji w każdej strategii, choć może nieco zbyt dużo za coś tak małe jak to jest określenie strategii każdy w oddzielnym module

Motorola. py

def formatbyte(n): 
    return "$%02X" % n 

def formatword(n): 
    return "$%04X" % n 

intel.py

def formatbyte(n): 
    return "%02Xh" % n 

def formatword(n): 
    return "%04Xh" % n 

Th pl, ponieważ moduły są pierwszorzędnymi obiektami w Pythonie, jak zauważyłeś, możesz je po prostu przekazać podczas używania swojej strategii.


Drugą alternatywą jest tylko za uboczny każdy element strategii jako parametr funkcji zwykłego na co są one używane w kodzie klienta na podstawie kontekstu. Na przykład zamiast

def some_func(obj): 
    obj.format_byte(...) 
    # other stuff 
    obj.format_word(...) 

Można mieć

def some_func(format_byte, format_word): 
    format_byte(...) 
    # 
    format_word(...) 

W każdym razie to nie ma sensu, aby przejść trasę OOP, jeśli masz nie więcej niż metody statyczne dla każdej strategii - nie ma dwóch instancje dowolnego typu będą się różnić, ponieważ nie ma żadnych danych instancji.

Powiązane problemy