php - Designing a service container: SRP, choosing the right creational pattern and avoiding tight coupling -
i'm writing own implementation of laravel service container practice design patterns , later make private microframework.
the class looks right now:
class container implements containerinterface { /** * concrete bindings of contracts. * * @var array */ protected $bindings = []; /** * lists of arguments used class instantiation. * * @var array */ protected $arguments = []; /** * container's storage used store built or customly setted objects. * * @var array */ protected $storage = []; /** * returns instance of service * * @param $name * @return object * @throws \reflectionexception */ public function get($name) { $classname = (isset($this->bindings[$name])) ? $this->bindings[$name] : $name; if (isset($this->storage[$classname])) { return $this->storage[$classname]; } return $this->make($classname); } /** * creates instance of class * * @param $classname * @return object * @throws \reflectionexception */ public function make($classname) { $refobject = new \reflectionclass($classname); if (!$refobject->isinstantiable()) { throw new \reflectionexception("$classname not instantiable"); } $refconstructor = $refobject->getconstructor(); $refparameters = ($refconstructor) ? $refconstructor->getparameters() : []; $args = []; // iterates on constructor arguments, checks custom defined parameters // , builds $args array foreach ($refparameters $refparameter) { $refclass = $refparameter->getclass(); $parametername = $refparameter->name; $parametervalue = isset($this->arguments[$classname][$parametername]) ? $this->arguments[$classname][$parametername] : (null !== $refclass ? $refclass->name : ($refparameter->isoptional() ? $refparameter->getdefaultvalue() : null)); // recursively gets needed objects class instantiation $args[] = ($refclass) ? $this->get($parametervalue) : $parametervalue; } $instance = $refobject->newinstanceargs($args); $this->storage[$classname] = $instance; return $instance; } /** * sets concrete implementation of contract * * @param $abstract * @param $concrete */ public function bind($abstract, $concrete) { $this->bindings[$abstract] = $concrete; } /** * sets arguments used class instantiation * * @param $classname * @param array $arguments */ public function setarguments($classname, array $arguments) { $this->arguments[$classname] = $arguments; } } it works fine see violation of srp in make() method. decided delegate object creational logic separate class.
a problem encountered class tightly coupled container class. because needs access $bindings , $arguments arrays, , get() method. , if pass these parameters class, storage still stays in container. architecture wrong , need, like, 2 more classes: storagemanager , classfactory. or maybe classbuilder? , should classfactory able build constructor arguments or needs class — argumentfactory?
what think guys?
Comments
Post a Comment