I have an interface, an abstract class, and three different classes, which can be morphed into other class of the same level.
The problem is, how to implement this kind of structure without violating the SOLID principles, or what’s the best way to transform a class into another similar class, but with some restrictions?
The restrictions are:
- Type 1 can morph into Type 2;
- Type 2 can morph into Type 1 or Type3;
- Type 3 cannot morph into anything;
<?php interface TestInterface { public function morph(TestInterface $ newClass); } abstract class Test implements TestInterface { private $ param; private $ code; public function setParam($ param) { $ this->param = $ param; } public function getParam($ param) { return $ this->param; } } class Test1 extends Test { private $ code = 1; public function morph(TestInterface $ newInstance) { if (!$ newInstance instanceof Test2) { throw new \Exception(); } $ newInstance->setParam(1); return $ newInstance; } } class Test2 extends Test { private $ code = 2; public function morph(TestInterface $ newInstance) { if (!$ newInstance instanceof Test1 || !$ newInstance instanceof Test3) { throw new \Exception(); } $ newInstance->setParam(1); return $ newInstance; } } class Test3 extends Test { private $ code = 3; public function morph(TestInterface $ newInstance) { throw new \Exception(); //final } } $ t1 = new Test1(); $ t2 = new Test2(); $ t3 = new Test3(); $ t1->morph($ t2); //OK $ t1->morph($ t3); //NOT OK $ t2->morph($ t1); //OK $ t2->morph($ t3); //OK $ t3->morph($ t1); //NOT OK $ t3->morph($ t2); //NOT OK