2009-06-08 10 views
9

W typowym schemacie strategii każdą strategię definiujemy jako klasę. Czy nie możemy uczynić go funkcją i po prostu przypiszmy odwołanie do funkcji, gdy tworzymy instancję i pozwalamy obiektowi wywoływać tę funkcję?W "Wzorze strategii" nie możemy zrobić każdej strategii jako funkcji, ale nie jako klasy?

+0

Baw się z Javy w takim przypadku :) – Joey

+1

dlaczego? Java nie może obsługiwać odwołania do funkcji? –

+7

+1 za krytyczne myślenie o wzorach projektowych. Powiedziałbym, że wiele schematów projektowych wynika z korzeni niezdolności języka. Więc w wielu przypadkach wzorce nie są biblami :) – kizzx2

Odpowiedz

3

W najprostszych przypadkach można zamienić wzorce strategii na wskaźnik funkcji. Uważa jednak, że ta sprawa

class HourlyPayStrategy implements PayStrategy 
{ 
    public int calculate() 
    { 
     int x = doComplexOperation1(); 
     int y = doComplexOperation2(); 

     return x + y; 
    } 

    private int doComplexOperation1() 
    { 
     // ... 
    } 

    private int doComplexOperation2() 
    { 
     // ... 
    } 
} 

Gdybyśmy po prostu dał prosty wskaźnik funkcji, rzeczy zaczną się naprawdę owłosione, bo nie można już byłaby to coś (no, przynajmniej nie w sposób dobrze kapsułkach).

+0

Nie zgadzam się z tym. Niezależnie od tego, czy odwołasz się do HourlyPayStrategy, czy HourlyPayStrategy.calculate, nie ma znaczenia w kwestii refaktoryzacji lub enkapsulacji. –

+0

@DavidArno według twojej notacji Wierzę, że znałeś C#, który wykonuje dobrą robotę wykonując _eta expansion_. Ta notacja wcale nie jest łatwa do osiągnięcia w wielu językach: JavaScript, Ruby, Python, Java, OCaml even (mówienie z pamięci kilkunastoletniej), C++ (pytania: jak C++ 11 się z tym dzisiaj przejmuje?). – kizzx2

+0

W wielu językach, gdy oczekuje się parametru _function_ jako, różni się on od oczekiwania metody _method_, w której kompilator/środowisko wykonawcze musiałoby być przenoszone wraz z powiązanym obiektem. Więc tak, dla C# twoja argumentacja ma nogi. – kizzx2

4

W zależności od języka. W języku C# można uczynić go delegatem. W Javie będzie to raczej anonimowa klasa. W C++ można naprawdę uczynić z niego wskaźnik funkcji.

2

Oczywiście, chociaż przy użyciu obiektów można korzystać z dziedziczenia w sposób, w jaki nie można było korzystać z funkcji.

1

W języku C# można używać delegatów ze wzorem strategii. Spójrz na to blog post na przykład.

1

To, co dzieje się pod maską w większości implementacji C++, to prawie to, co sugerujesz. Kompilator zwykle rozwiązuje Strategy.virtualMethod call() tak (w pseudo kod):

 
    (Strategy.pVtable[indexOfVirtualMethod])() 

Więc jeśli jedynym zmartwieniem jest to jeden z bardziej dereferencji wskaźnika (pVtable) naprawdę powinieneś najpierw profil jeśli nie można zidentyfikować bardziej poważne hotspoty.

Mam wrażenie, że Twój kod będzie trudniejszy do zrozumienia i utrzymania, gdy użyjesz wskaźnika funkcji zamiast obiektu strategii.

Powiązane problemy