deadonarrival Posted March 7, 2008 Share Posted March 7, 2008 Further to my posts in this topic : http://www.phpfreaks.com/forums/index.php/topic,186075.0.html and my recent forays into the world of OOP: I see so many people asking, as I currently am - of the methods of calling one class/object from inside another. We even work out how to make an admin class which extends the user class - or whatever other circumstance. We're now at the end of what OOP tutorials seem to teach, but we're nowhere near at the point of making useable programs. Every OOP tutorial talks about classes, methods, objects, instances, properties etc... which is great. We all build up our classes, the functions work perfectly with each other. Then suddenly we need to use an error class, or query our database: and come unstuck. Now I've yet to find a tutorial that adequately covers this: some use the same method as I first used - simply extending classes one after another to get the useability of the previous classes. It works, but is totally missing the point of objects. Next is passing objects as arguments, which seems to be the preferred method and one I absolutely hate. It takes a lot longer, and is a pain if you ever want to change an object name. I suggested the idea in the above topic, just as one of my thought processes - I see it as a mix of procedural programming to choose the classes/objects and functions to call, in what order, and then the objects themselves. It seperates the objects from the processing of the objects. Eg my "user" doesn't try to decide which function to choose next, my script does that. It's my attempt to see objects like real world objects. My radio goes on and off, and it can be tuned - but it has yet to make a decision about what radio station I want... that's done by me, the user. I want to use the script to call the functions, with the functions doing the minimum amount possible. Basically every function does one small task - eg checks the username is in the database, or encrypts the password. Anyway, I've been told why this is wrong - although I'm still for the idea, why does every piece of code have to be part of an object? - and I'm back to square 1. So does anyone know a tutorial/article, or have some (detailed) thoughts on how this should all be done. I can't find anything but the phrases "singleton" and "don't use singleton" What's the best way, what's the way taught at university, what's the way that works the best. What's the most programmer friendly way? I understand PHP, I understand the concepts of OOP - I even understand a decent proportion of the "ideas" about code... but I just can't figure out this one thing. ANY thoughts or input would be great, obviously the more thought out the better. Any links would be superb too, I'll read anything on the subject just to have a crack at understanding it. Quote Link to comment Share on other sites More sharing options...
dbo Posted March 8, 2008 Share Posted March 8, 2008 Loose coupling is a good idea, regardless of approach chosen. I'll leave that debate up to the experts, but in general unless there is an obvious reason to relate classes you want them to be able to exist on their own. If you can accomplish this you are able to make changes to code and not have to worry as much about it breaking what you would think is otherwise unrelated. Quote Link to comment Share on other sites More sharing options...
deadonarrival Posted March 8, 2008 Author Share Posted March 8, 2008 But how about when you want to send errors (although extending the exception class would work here - so maybe not quite such a good example) or access a database? Sometimes classes do have to call one another. Quote Link to comment Share on other sites More sharing options...
448191 Posted March 8, 2008 Share Posted March 8, 2008 Next is passing objects as arguments, which seems to be the preferred method and one I absolutely hate. It takes a lot longer, and is a pain if you ever want to change an object name. What do you mean by "takes a lot longer". And objects do not have names. Variables have names, so do classes. Objects are values, and values do not have names. Changing a class name is no more an issue than changing a function name. Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted March 8, 2008 Share Posted March 8, 2008 The reason why we cannot give you a simple answer is because it's a complex problem. There is no golden solution to how you should do it, but there are however solutions which are not good. Entire books are written about this subject so it's hardly something anyone can sum up in a single post. Quote Link to comment Share on other sites More sharing options...
deadonarrival Posted March 8, 2008 Author Share Posted March 8, 2008 But if I have $database = new db(); If I'm passing the database to several functions, I have to use the variable $database several times. If I later want to use two different connections, the only way to do it would be to add another variable, or change the $database into something more meaningful. $database and $database2 aren't very good. $localdb and $remotedb are more helpful... but I'd have to change every function. Thanks for the thoughts daniel0 - could you give any suggestions on some of these ideas? Quote Link to comment Share on other sites More sharing options...
dbo Posted March 8, 2008 Share Posted March 8, 2008 This is most likely where you would want to use a singleton. You only want one open DB connection. Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted March 8, 2008 Share Posted March 8, 2008 A registry might be better than a singleton in this case seeing as although you might only need one connection right now, this need might change later on. If you used a singleton then you would only be able to have one database connection and you would have to change your code everywhere the database is used, but that would be really tedious. If you used a registry you could just add another connection to it or have one (the "normal" connection) connection in the registry and create the additional instances as needed. This is of course if you don't like to pass the instances by argument. Quote Link to comment Share on other sites More sharing options...
dbo Posted March 8, 2008 Share Posted March 8, 2008 Well yeah... but I was thinking more along the lines of someone new to OOP they probably aren't going to be doing anything that sophisticated right now. Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted March 8, 2008 Share Posted March 8, 2008 My point is that the needs might change and you must take that into account when designing your application. Here is another example: When deciding how to integrate the forums with the main site we're currently rebuilding, we had to choose whether to use SMF's SSI.php or write our own code(/classes), we choose the latter option because the former would couple the forums too much with the main site, and should the choice of forum change there would be far too much work in updating the main site's code. Quote Link to comment Share on other sites More sharing options...
dbo Posted March 8, 2008 Share Posted March 8, 2008 Right... we're saying the same thing. I'm agreeing with you. I'm just saying that for a person new to OOP that a singleton would most likely work and be easier to understand. For larger applications, you're absolutely right... not disagreeing Quote Link to comment Share on other sites More sharing options...
deadonarrival Posted March 8, 2008 Author Share Posted March 8, 2008 This is my first run-through of a proper program with OOP, so the simpler one which does the job now will be preferred - I can delve into the more complex aspects once I've gotten used to the more basic ways of working with classes etc. Any decent singleton tutorials? Wikipedia isn't a lot of help on this one - or Google for that. Edit: "Singleton Pattern" gave better search results - but still not a nice basic tutorial, so any would still be great. Quote Link to comment Share on other sites More sharing options...
448191 Posted March 8, 2008 Share Posted March 8, 2008 Singleton is one of the simplest patterns in existence. 1) Declare a constructor private. 2) The single instance of the class is "stored" in a static class member. 3) Provide a static method to fetch the static instance of the class. If it doesn't exist yet, create it (in the static method). Surely you do not need a tutorial for these three simple tasks? Quote Link to comment Share on other sites More sharing options...
deadonarrival Posted March 8, 2008 Author Share Posted March 8, 2008 I've had a look and I get the theory, but I'm not sure how to put it into actual code in a real-world situation. Quote Link to comment Share on other sites More sharing options...
dbo Posted March 8, 2008 Share Posted March 8, 2008 This isn't so much a tutorial as an article that helps explains some different patterns. It's a pretty decent read. It does however show some brief examples that illustrate usages. In fact, the example use with the Singleton Pattern is one for a DB connection. http://www-128.ibm.com/developerworks/library/os-php-designptrns/ To 448191: I respect your opinions and knowledge when it comes to PHP and design. However, I've got to respectfully disagree with your response in this case. Despite being simple and easy to implement, it is often hard to grasp concepts without seeing them put to use. I don't think deadonarrival's request is inappropriate, nor did it merit your response in this case. Quote Link to comment Share on other sites More sharing options...
448191 Posted March 8, 2008 Share Posted March 8, 2008 I know the tone of posts don't always come across right, if that's what you're saying. I still don't think something as simple as a Singleton warrants a tutorial. I am also most definitely not impressed with quality of tutorials on design patterns out there, specifically the ones with PHP examples. Buy a book, a good one. Quote Link to comment Share on other sites More sharing options...
deadonarrival Posted March 9, 2008 Author Share Posted March 9, 2008 That's great dbo, thanks. Certainly a help And 448191 - I'm thinking of buying a book; I usually do for each topic - but this one seems very divided and it's taking me a while to find one I like. Quote Link to comment Share on other sites More sharing options...
448191 Posted March 9, 2008 Share Posted March 9, 2008 Ok, here's you Singleton "tutorial": 1) Declare a constructor private. class Foo { private function __construct(){ //Do something } } 2) The single instance of the class is "stored" in a static class member. class Foo { private static $instance; private function __construct(){ //Do something } } 3) Provide a static method to fetch the static instance of the class. If it doesn't exist yet, create it (in the static method). class Foo { private static $instance; private function __construct(){ //Do something } public static function getInstance(){ if(self::$instance === null){ self::$instance = new self(); } return self::$instance; } } There, you have a Singleton. Now a real world example using a Layer Supertype and a Factory Method: <?php abstract class Database { private static $instance; final protected function __construct($dsn){ $this->connect($dsn); } public static function factory($dsn = null){ if(self::$instance === null){ if($dsn === null){ throw new Exception('Database not initialized.'); } $class = ucfirst(substr($dsn, 0, strpos($dsn, ':'))); if(!class_exists($class)){ throw new Exception('Database type "'.$class.'" not supported.'); } self::$instance = new $class($dsn); } return self::$instance; } abstract public function connect($dsn); abstract public function query($str); } class Mysql extends Database { public function query($str){ //Perform query } public function connect($dsn){ //Establish connection } } $db = Database::factory('mysql:host=localhost;dbname=test'); $assertion = ($db === Database::factory()); var_dump($assertion); ?> Result: only one instance of a implementation of "Database" at all times. Oh, and check out "Recommended Books" in the nav of my blog (in my sig). The Matt Zandstra book is the only decent book with PHP examples I've come across, but you really should read the other three as well, if you are serious about learning Design Patterns. Quote Link to comment Share on other sites More sharing options...
deadonarrival Posted March 9, 2008 Author Share Posted March 9, 2008 Thanks 448191 - I'll give that a good look through and try applying it to my program Quote Link to comment Share on other sites More sharing options...
koen Posted March 9, 2008 Share Posted March 9, 2008 You may want to declare a private __clone() method to the singleton too. Quote Link to comment Share on other sites More sharing options...
Jenk Posted March 11, 2008 Share Posted March 11, 2008 Singletons are restrictive, and can (but don't neccessarily do) lead to problems later in application life. Just be more disciplined and only instantiate the object once if you want to maintain only once instance. As for the variable/object name argument (which has already been addressed I see,) you are mistaken. An example: <?php $foo = new db(); function foobar ($bar) { $bar->connect(); } foobar($foo); ?> Quote Link to comment Share on other sites More sharing options...
deadonarrival Posted March 11, 2008 Author Share Posted March 11, 2008 I was only intending to use one for the database, it occured to me to use one for errors, but I think now that I'll extend the exception class and use that instead. Seems more intellligent. Quote Link to comment Share on other sites More sharing options...
448191 Posted March 11, 2008 Share Posted March 11, 2008 Singletons are restrictive, and can (but don't neccessarily do) lead to problems later in application life. Just be more disciplined and only instantiate the object once if you want to maintain only once instance. What happened to 'Singletons are icky'? Quote Link to comment Share on other sites More sharing options...
Jenk Posted March 13, 2008 Share Posted March 13, 2008 I decided to be more verbose. 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.