Delegacja ------------------------------------- Delegacja pozwala zmienić zachowanie jednej (wybranej) metody lub kilku metod klasy bez zmiany jej typu (a przynajmniej - bez zmiany intyerfejsu). Osiąga się to przez schowanie obiektu klasy bazowej w środku obiektu klasy potomnej i odpowiednim przekierowaniu wywołań. .. literalinclude:: ProstaDelegacja.py :language: python :linenos: Zauważ, że delegacje bardzo przypominają Pythonowe dekoratory. .. note:: Delegacja opiera się na zawieraniu obiektu - obiekt klasy ``InnerClass`` jest schowany wewnątrz ``SimpleDelegation``. Ten sam efekt można osiągnąć, wykorzystując **dziedziczenie** Drugi przykład jest już bardziej praktyczny. Poniżej zdefiniowano klasę bazową ``AtomSelector``, która *zaznacza* bądź *nie zaznacza* podane atomy. Klasa ta jest tylko **interfejsem**, definiuje metodę która pojawi się w klasach potomnych. Następnie zdefiniowano dwa *konkretne* selektory (``SelectCA`` który zaznacza węgle alfa oraz ``SelectHeavyBB`` do zaznaczania ciężkich atomów łańcucha głównego białka). .. literalinclude:: atom_selectors.py :language: python :linenos: Meritum tego przykładu (wzorzec delegacji) pojawia się w klasie ``InvertSelector``, do odwrócenia zaznaczenia dowolnego obiektu. Sama klasa ``InvertSelector`` nie wie, co ma zaznaczyć; jedynie wykorzystuje do tego celu podany selektor (przechowywany jako prywatne pole klasy ``self.__selector``), traktując go jako *czarną skrzynkę*. Następnie stosuje operator logiczny negacji do otrzymanego wyniku. Zauważ, że efektu tego nie można by uzyskać przez dziedziczenie. Owszem, można np. odziedziczyć po klasie ``SelectCA`` aby odwrócić to zaznaczenie: .. code-block:: python :linenos: class SelectNotCA(SelectCA) : def __call__(self, atom): return not self.__selector(atom) Klasa ``InvertSelector`` jednak może coś więcej: ona odwraca dowolne zaznaczenie, podane jako argument dla jej konstruktora. Kolejnym selektorem z delegacją jest ``LogicORSelector``, który zwraca prawdę, gdy choć jeden z selektorów jest spełniony Zauważ, że ``InvertSelector`` oraz ``LogicORSelector`` są typu ``AtomSelector`` (dziedziczą po nim).