Sage предоставляет эту функциональность, по существу используя «умный взлом», описанный @Ayman Hourieh, но встроенный в модуль в качестве декоратора, чтобы обеспечить более чистый внешний вид и дополнительную функциональность - вы можете выбрать оператора для перегрузки и, следовательно, порядок
from sage.misc.decorators import infix_operator
@infix_operator('multiply')
def dot(a,b):
return a.dot_product(b)
u=vector([1,2,3])
v=vector([5,4,3])
print(u *dot* v)
# => 22
@infix_operator('or')
def plus(x,y):
return x*y
print(2 |plus| 4)
# => 6
Для получения дополнительной информации см. документацию Sage и этого билета отслеживания улучшений .
Адаптер адаптирует данный класс / объект к новому интерфейсу. В первом случае обычно используется множественное наследование. В последнем случае объект оборачивается соответствующим объектом адаптера и передается. Проблема, которую мы здесь решаем, связана с несовместимыми интерфейсами .
Фасад больше похож на простой шлюз со сложным набором функций. Вы делаете черный ящик, чтобы ваши клиенты меньше беспокоились, т.е. упрощаете интерфейсы .
Прокси предоставляет тот же интерфейс, что и проксируемый класс, и обычно выполняет некоторые служебные действия самостоятельно. (Таким образом, вместо создания нескольких копий тяжелого объекта X
вы делаете копии облегченного прокси P
, который, в свою очередь, управляет X
и переводит ваши вызовы по мере необходимости. ) Вы решаете проблему клиента: не нужно управлять тяжелым и / или сложным объектом .
Декоратор используется для добавления пороха к вашим объектам (обратите внимание на термин «объекты» - вы обычно динамически декорируете объекты во время выполнения). Вы не скрываете / не нарушаете существующие интерфейсы объекта, а просто расширяете его во время выполнения .
Теперь, когда у вас задействован декоратор, вы, вероятно, захотите узнать, почему упор делается на слово «объект» - некоторые языки (например, Java) просто не позволяют виртуальное наследование (то есть множественное наследование, как это делает C ++), чтобы позволить вам выполнить это во время компиляции.
Поскольку мы перетащили множественное наследование (и ужасный ромб), вы будете искать миксинов , которые представляют собой упорядоченное линейное объединение интерфейсов , чтобы обойти проблемы множественных наследование. Однако миксины не так хорошо смешиваются. И мы получаем черт - да, те маленькие кусочки поведения без состояния , которые вы постоянно видите во всплывающих окнах в параметрах шаблонов в C ++. Черты пытаются элегантно решить проблемы композиции и декомпозиции поведения, не прибегая ни к множественному наследованию, ни к упорядоченному построению цепочек.
Фасад
Вы можете использовать фасад, например, чтобы упростить вызовы API. Посмотрите на этот пример удаленного фасада. Идея здесь заключается в том, что полная реализация кода на сервере скрыта от клиента. Клиент вызывает 1 метод API, который, в свою очередь, может сделать 1 или более вызовов API на сервере.
Адаптер
Хороший пример этого можно найти здесь, в Википедии. Клиентский объект Source
хочет вызвать метод другого объекта Target
, но интерфейс этого другого объекта отличается от того, что ожидает клиент.
Введите объект адаптера.
Он может принять вызов от объекта Source
и за кулисами вызвать метод Target
, который должен быть использован.
Source->CallMethodAOnTarget() ---< Adaptor.CallMethodAOnTarget() this calls ---> Target.MethodWithDifferentSignatureAndName(int i)
Что касается Proxy, то у меня нет опыта использования этого паттерна проектирования.