У вас есть цепочка наследования, и вы хотите изменить базовую реализацию для каждой базы проекта, сохраняя при этом общий код и типы (и не подвергаясь строгому изменению существующих проектов).
Способ состоит в том, чтобы отделить общую функциональность от настроек, специфичных для проекта. Используйте шаблон декоратора, который даже позволяет вам обмениваться настройками между проектами.
Ваша ситуация для всех существующих проектов:
A <- B <- C
A->a()
B->a(), B->b()
C->a(), C->b(), C->c()
Ваш новый проект (скажем, проект 1) должен иметь:
A1 <- B <- C
A1->a(), A1->a1(),
B->a(), B->a1(), B->b()
C->a(), C->a1(), C->b(), C->c()
Шаблон декоратора требует, чтобы вы создали декоратор для каждого объекта, который вы хотите расширить (A1, B1, C1). Вы хотите, чтобы пользовательские методы A1 также были доступны в ваших декорациях B1 и C1, поэтому вам нужно связать их так же, как и исходные классы.
A1 decorates A
B1 decorates B
C1 decorates C
A1 <- B1 <- C1
A1->a1()
B1->a1()
C1->a1()
Вы по-прежнему хотите, чтобы функциональность A, B, C также присутствовала в ваших классах декорирования, поэтому вам нужно создать связь между каждым декоратором и его исходным классом декорирования и делегировать соответствующие методы:
A1 hosts a reference of A
B1 hosts a reference of B
C1 hosts a reference of C
A1->a() ----> $this->myA->a();
B1->a() ----> $this->myB->a();
B1->b() ----> $this->myB->b();
Все пользовательские методы проекта 1 выполняются напрямую:
A1->a1() ----> $this->a1();
В вашем новом проекте 1 вы используете:
A1 instead of A
B1 instead of B
C1 instead of C
Вашим A1, B1 и C1 может быть разрешено создавать свои экземпляры A, B, C прямо в их конструкторе, хотя вы можете пропустить эти экземпляры, чтобы включить несколько декораций. В этом случае вам понадобятся надлежащие интерфейсы, скажем, IA, IB, IC. Тогда у вашего A1 может быть метод setA(IA theA)
, где theA может быть точным A или даже A1, A2 или A3 ... Но это более продвинутое, и вы найдете больше информации, погуглив образец декоратора, и вам, возможно, понадобится немного немного опыта работы с интерфейсами и полиморфизмом.
Итого:
Оставьте вашу цепочку наследования такой, какая она есть
Создание цепочки декораторов для каждого индивидуального проекта
Свяжите декораторы с их исходным классом и делегируйте общие функции.
Используйте декораторы вместо оригинальных классов в вашем пользовательском проекте. Теперь они идентичны своим оригиналам и имеют дополнительные методы, которые вы хотите добавить.