topcat Posted April 4, 2013 Share Posted April 4, 2013 Hi there, I have been writing my own MVC framework which is basically a lightweight version of ZF1. One thing I am tying to improve on in my version is the decoupling of objects. As I am on a tight deadline I decided to implement Zend_DB until I can develop/find a better alternative, I quickly realised that all of the Zend components have their own error objects which extend the PHP Exception object, this obviously creates a dependency, if you don't use Zend framework then you do not have access to the Zend_Db_Exception object. To avoid this I was thinking of injecting the name of a specialised error class in the constructor call to each of my classes. It would not make sense to pass an error object instance as there may be more than one error object required but I could pass the class name and initialise an error object using the class name from within each object. DI is something that I am aware of as a concept but have had no practical experience of implementing and I was wondering what people thought of the approach I intend to take? Alternatively if someone is aware of a common clean technique for error handling without adding dependency and coupling I'd love to hear about it. Cheers. An example: class router{ private $error_class public function __construct(Array $Params = Array()){ $this->error_class = $Params['error_class_name']; ... } public function routeStuff($url){ try{ ...... }catch($e){ throw new $this->error_class("something went wrong"); } } } Quote Link to comment Share on other sites More sharing options...
trq Posted April 4, 2013 Share Posted April 4, 2013 I would suggest that the whole issue revolves around the fact that your using ZF1 components which are out of date and (as you can see) are not very easily used as stand alone "components". Why don't you use ZF2 stuff? or Symfony2 stuff, or Laravel stuff or any other modern framework that uses namespaces, PSR-0 and composer ? This, would solve a number of your issues out of the box. Injecting a string and relying on that being a valid class name for a class that may or may not exist just seems very unreliable. If your going to "inject" something, it should be an object that implements some interface. You then rely on the interface, not the implementation. Quote Link to comment Share on other sites More sharing options...
topcat Posted April 4, 2013 Author Share Posted April 4, 2013 Thanks for the reply trq. I see your point and agree with it. However I also don't like the idea of instantiating an object that may not (and hopefully will not) be used. It doesn't feel right either. If this were a functional component which will definitely be required by the class I wouldn't consider any other option other than instantiating the object and injecting it in the constructor, eg if it were a db connection object etc. but that isn't really the case. To be honest I'm using ZF1 components because I have used them a lot and I am familiar with them. I don't really have the time right now on this project to learn another framework from the ground up. Especially ones such as zf2 or Symfony2 which have a completely different design principle to zf1.I will take a look at some zf2 classes to see how they implement error handling. Quote Link to comment Share on other sites More sharing options...
trq Posted April 4, 2013 Share Posted April 4, 2013 I'm not saying you need to learn some other framework from the ground up. I'm saying these frameworks are much better designed and are much less tightly coupled. For instance, you should be able to install whatever database stuff Zf2 now provides (I don't use Zf1 or Zf2) via composer and this will install everything it needs to work. It's actually pretty hard to see from your example what your stuck on. I meen, it looks like "your" router class, surely it should know what type of exception it is going to be throwing? I meen, any calling code is going to need to know what exception is being thrown too, how do you propose that is handled? Anyway, if you don't want to be injecting actual objects, you could go down the path of IoC containers and all that jazz. Iv'e built them before and a simple implementation is just that, simple, it's only as you start adding more functionality that they become more complex. Quote Link to comment Share on other sites More sharing options...
topcat Posted April 4, 2013 Author Share Posted April 4, 2013 (edited) Again, thanks for the reply, I appreciate your time.The calling code does not need to know what type of error object has been created in the router (in this example), only that it is an instance of the Exception class (which it will be as all exception classes would be a child of Exception) the exception object is then just dispatched to an error controller which logs the error and displays the details in a view script for debugging.My understanding of DI at least at a basic level was that the poiint (or at least a point) was to inject classes depended on by another class rather than instantiating them within the "consuming" class. This avoids the refactoring required if for any reason you wish to substitute the injected class for another at some point. Eg as I wish to do so now by using my own error objects rather than Zend's error classes. Basically to remove coupling based on dependency? Edited April 4, 2013 by topcat Quote Link to comment Share on other sites More sharing options...
trq Posted April 4, 2013 Share Posted April 4, 2013 My understanding of DI at least at a basic level was that the poiint (or at least a point) was to inject classes depended on by another class rather than instantiating them within the "consuming" class. This avoids the refactoring required if for any reason you wish to substitute the injected class for another at some point.That is indeed correct. However there is no point passing any old object into a class if that class doesn't know what to do with it. Hence, most people use type hinting along with dependency injection so as to ensure there is some form of contract between the two classes.I wish to do so now by using my own error objects rather than Zend's error classesThat was what I was trying to get at. Why are you using Zf1's error classes within your own router? Quote Link to comment Share on other sites More sharing options...
topcat Posted April 4, 2013 Author Share Posted April 4, 2013 Aha I see the confusion - the example was a purely abstract one simply to show my thinking regarding the instantiation of a named class. Sorry about that. Should have made it clearer that this was a hypothetical scenario. The actual issue I am facing is that when I use Zend_Db if there is any error with the SQL statement then it tries to throw a Zend_Db_Exception. However Zend_Db_Exception is not available in my framework. I realise that I could easily make it available but this is avoiding the issue rather than solving it. I wish to remove this dependency. Also I do not want to substitute it with another dependency by simply replacing all of the Zend_Db_Exceptions with my own hardcoded classes. I would have the same situation if I wished to move the component to another system later on. Quote Link to comment Share on other sites More sharing options...
trq Posted April 4, 2013 Share Posted April 4, 2013 So you plan on hacking the Zend_Db class so that it no longer has this dependency hard coded? That still doesn't sound like a decent solution. Quote Link to comment Share on other sites More sharing options...
topcat Posted April 4, 2013 Author Share Posted April 4, 2013 Any ideas what a neat solution could be? Still looking at zf2 classes at the moment. Cheers. Quote Link to comment Share on other sites More sharing options...
topcat Posted April 4, 2013 Author Share Posted April 4, 2013 Actually looking at ZF2 the exceptions are still hardcoded however the exceptions seem much more standardized across all components with each exception being defined within each namespace. So there is at least no dependency on a file outside the namespace used by that particular component. Quote Link to comment Share on other sites More sharing options...
trq Posted April 4, 2013 Share Posted April 4, 2013 That doesn't sound any different to the example you told us about in Zend_DB and Zend_DB_Excpetion. They are both in the pseudo DB namespace. It's a nice idea to try and decouple your components as best you can but going as fare as removing all hard coded dependencies is not always achievable nor really required. A few exceptions, utilities and other bits and pieces are always going to be excepted as dependencies and no one is really going to be looking to swap these things out or test your components within mocked versions of these things anyway really. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.