Friday, February 20. 2009SOAP Kills
So I am working on a new assignment at work yesterday, should be a pretty simple task I think. I am consuming a SOAP service to get some simple data. Little did I know that it was such a pain to work with .Net when you are using the PHP SOAP extension. I started out with the following WSDL (just a portion that I wanted to work with is listed).
So I write up a quick test script to grab that WSDL and try to run a method on it. It looked something like this: Easy-peasy, I have working with PHP driven SOAP services a bunch of times before so I could pretty much write that off the top of my head. So I run the code and I get a SoapFault saying that the Content-type is text/xml when it was expecting application/soap+xml. So I Google around and find that I have to specify the soap version 1.2 in order to get the correct Content-type. So I make the following change to $clientOptions: Nice, that error is fixed. But Now I have another SoapFault: "The SOAP action specified on the message, '', does not match the HTTP SOAP Action. Google again. This time it looks like the PHP soap client is not able to deal with WSHTTP binding and must use the basicHTTP binding. I am not authenticating for this SOAP service, so I am not sure why it even matters. Luckily, the WSDL tells me that I have basicHTTP bindings available. When I try to use the basic data source though, I get another SoapFault "Action /basic is not defined". So then I email the provider of the feed to make sure their basic binding is configured correctly and working. They make some changes and end up dropping the WSHTTP binding completely from the WSDL. Sweet, that error is fixed. Except that I am getting another SoapFault, fortunately for me I have run across it aready in my little adventure. It is now complaining that the Content-type application/soap+xml is incorrect as it was expecting text/xml. Seriously! So I go and remove the soap_version element from the $clientOptions array. Awesome, that was an easy one to fix! But now I have another SoapFault: "Object reference not set to an instance of an object.". Google again. This is where things get really annoying. First of all, the SoapFault error message is ridiculously cryptic. I find all kinds of forum posts and comments in the PHP manual about how you are supposed to pass parameters into the action method on your client. Here are some of the different versions that I tried: No good. No good. No good. No good. Then I tried adding 'classmap' => array('ListByCode', 'ListByCodeRequest') to the $clientOptions array. That didn't work either. Please bear in mind that these changes may appear to be the flapping around of a dying fish, but I assure you that they each involved several minutes of Google research. I will admit though that by this point I was feeling fairly desperate. I decided to go get a copy of soapUI to see if maybe the feed itself wasn't working. I import the WSDL click on LIST and hit run. Bam! Results are returned immediately. I calmly stand up and leave my office before I bring violence upon my computer. 15 minutes pass Okay, so I return to me desk and decide to look ONLY at the requests I was making and try to get them to match the ones created by soapUI. Here's what soapUI was doing: And here is what I was producing: So obviously my parameters where not being passed in. I tried making the following change: Which results in this request: Snap! I am getting a different SoapFault saying that param1 is basically an unknown parameter. I proceed to try several versions of nested arrays and finally give up after this one: You see I am back to the whole "Object reference not set to an instance of an object." SoapFault. It is then that lightening comes down and strikes my brain. This is the final (and working) version of the script: So, hopefully this little saga will help others that are in danger of having a very long day as I had escape their fate. On a side note, whenever I am doing this kind of research on Google I always wish that there was an option to specify how old the results should be. I have the option Search: [ ] the web [ ] page from Canada, but I'd really like to see [ ] from this month [ ] from this year [ ] any time as options as well. A blog post mentioning PHP and SOAP from 2003 is probably not going to be helpful. Although sometimes I can see the date it was written before I click, not seeing the entry at all would be great. Thursday, January 29. 2009Enterprisey PHP
I hear a lot of talk about the use of PHP in the Enterprise, recently there was even a white paper circulated extolling the virtues of PHP and attempting to make the case that PHP should be the language of choice for Enterprise development. Although the paper does bring up some interesting points such as the large number of extensions and the fact that there are a number of bridges for PHP to load native code written in Java and other languages, taking away from these strengths was that there is way too much emphasis placed on how many websites run PHP. Although it is hard to argue with the fact that PHP is greatly suited to web development, that in no way translates into suitability for Enterprise development. No offense to the language, but I find it perfectly understandable that PHP is not often considered a language suitable for Enterprise development.
PHP developers have a love-hate relationship with Java. Many PHP'ers are quick to point out that "PHP is not Java" and yet when one considers some of the most recent waves in PHP interest, they are frequently things that have been around in the Java world for years and are just now being introduced into PHP. A couple of recent examples are the sudden surge in PHPUnit and phpUnderControl. The latter isn't even a fully native PHP solution but en extension of the venerable Cruise Control continuous integration suite. That being said, I use both of those extensively and they form a crucial part of my software development process. Unfortunately, I feel that the adoption of these technologies has started to plateau as the initial wave of blog posts and general buzz have died down. Many PHPers feel that it's just too much effort for what it's worth. This is the key to the whole debate in my opinion. PHP developers put everything behind speed when it comes to development, in fact I often see bad code decisions being made for the benefits of a few CPU cycles. Perhaps it's because the speed of PHP is the primary strength that developers point to when comparing it to other languages that they focus on that feature. Honestly, PHP should be the fastest language on the web, after all it's all it's done for the last decade. Here's what you should take away from this post: 1) Using PHP does not make you cooler. It should mean that you have chosen the right tool for the job. There is a reason why Zend Studio (from Zend, The PHP Company) is written in Java and not PHP-GTK. Why be just a PHP developer when you can be a programmer with many tools at your disposal. 2) If you want to improve the way PHP is considered in terms of The Enterprise, make your code look like it was written for the Enterprise. Stop considering your software to be something that you will write and throw away. Write it like it's something you will have to maintain for a decade and some day you just might get to. Friday, January 16. 2009
Deep Simplicity Part 9 Posted by Matthew Purdon
in Software Development at
07:22
Comments (2) Trackbacks (0) Deep Simplicity Part 9
So this is the last rule in the Deep Simplicity series. This time we will be talking about rule #9: Don't use Getter/Setters/Properties At first, I was confused about the rule because the main advantage of OOP is that you have the data and the methods that work on that data in the same place. I have often complained about the ridiculous idea that you should just blanket generate getters and setters for every single property. This leads to copy and paste errors and in my opinion a class that is totally bloated with useless methods. This idea is more in keeping with the spirit of rule 9.
The basic idea is that if you just give blanket access to your properties then you are allowing the client code to ignore encapsulation and in doing so you are allowing operations on your object's dirty bits to take place outside of your class. As usual, allowing this to take place is not a good idea. Take a look at this code: The Order::getTotal knows way too much about the product object. What happens if there are other factors in determining the price after taxes? Are you going to put all of that logic into the getTotal method as well? What happens if you want to calculate the price after taxes without having an order? Code duplication results in multiple places for possible bugs if the spec changes, you have to "remember" where those calculations are done in order to update them all. Encapsulation solves this problem by making one and only one logical place for functionality to reside. It's hard to remember all of the places that code should change if you have never seen it before. Here is the same functionality with no access to the Product's private parts: Wow, not a single accessor in sight. Once again the code we end up with looks much cleaner than the original. The semantic intent is clear and more importantly, this new method is much more likely to be reused. In the end these rules are meant to be a means to an end. You can always come up with edge cases and exceptions to the rules where you find that the code you end up with is maybe not as good as it could have been. The point is not that you follow these rules to the letter or die trying; the point is that by thinking about these rules as you write code you will end up with something that is far better than you would have otherwise done. I hope that the examples I have given have shed some light on how simple and understandable your code can become with a little more effort on your part. If you are interested in more of the great ideas from Thoughtworks, make sure you grab The Thoughtworks Anthology. Tuesday, January 13. 2009
Deep Simplicity Part 8 Posted by Matthew Purdon
in Software Development at
12:32
Comments (0) Trackbacks (0) Deep Simplicity Part 8
Okay, back to the rules! Rule #8 is: Use First-Class Collections. Unlike the previous rule, I really like this one. Basically the rule states that any class that contains a collection should have no other instance variables. This is similar to other Deep Simplicity rules in that it makes it clear what the responsibility of the class is.
On top of this, a simple array has very little semantic intent other than the name that a developer gives the variable that contains it. As we have discussed before lazy programmers can take your well-meaning code and pervert it into meaningless spaghetti by simply chopping a few characters off of a variable name. By making the collection a full-blown object in it's own right it also becomes clear where you should put helper code like filtering or applying a function to all members of the collection. Let's take a look at some code: So, this is some seriously lazy programming. Although there are a few comments, they are very sparing. The short variable names give you no real clue about what the four arrays represent - at least not without having to expend some brain power figuring out what all of this means. I know you may be saying to yourself that this is a poor example, but I assure you, I have seen code like this in production all the time. I think it's a legacy of the PHP developer lifecycle, starting with one-off single page scripts and eventually evolving into more. Let's see the code again with some more comments and better variable naming: So this example is much more clear in terms of intent. Although you can now determine what each of the arrays is representing, you have to do a lot of parsing in order to determine what is going on. On top of the difficulty in understanding what is going on, there are lots of bug-prone areas where you deal with the fact that arrays are 0 indexed. such as this line: Now, some of you are saying that getting a random card from an array of cards should be extracted into a method. I agree with you completely! The questions is, where? Should we put all of this in a Game class which has a Game::getRandomCard(array $cards) method? When you are playing "Go Fish" is there some game device that a player passes their hand into to get a random card? I don't think so. If however, you take the advice of this rule and make all of these arrays into first class objects, it becomes quite clear where that method belongs: I don't know about you, but this last example seems very clear in terms of what's going on. Even if a lazy developer where to come along and started changing the variable names to three or less characters in length, things still make sense with minimal effort because the logic is hidden away in the Collection itself rather than getting in the way of getting work done. One more rule to go: #9 Don't user any Getters/Setters/Properties Wednesday, January 7. 2009
Deep Simplicity Part 7 Posted by Matthew Purdon
in Software Development at
16:01
Comment (1) Trackbacks (0) Deep Simplicity Part 7
In this entry I am going to talk about rule #7: Don't Use Any Classes with More Than Two Instance Variables. This for me is one of the hardest rules to try to follow. The author of Deep Simplicity states that he is about to release a one hundred thousand line application that strictly follows these rules, so I guess I just suck.
The reason that we can break any object down to have one or two instance variables is because when you have more than two of them, you can usually group two into one object. Adhering to this rule makes for logical code that has a very defined responsibility. This after all is the whole point to these rules; making it so that everything is so simple it requires little to no thought to work on the project. Let's look at some code: So we have all seen the classic User object, you might be wondering how we can get this object to have one or two instance variables. You can do it by either working your way down by splitting an object into related halves or working your way up by taking any to instance variables and making an object out of them. So let's try it: So there we have it. The User object was broken down into finer grained objects that can then house the logic specific to those properties. It's pretty sweet when it works out that way, but in the interest of full disclosure I'll admit that I have no idea how to break up the original User class I was going to use for this example: To me, that is more like the User objects I see all of the time. I can still break it up into Name and ContactInformation. ContactInformation can be broken down into Address and PhoneNumbers, but I can't think of a way to break up this object: To me, every property in there belongs to an address. Further, I can't think of a way to group any two of these properties into a new object or a way to split this object in half. Can you see a way to split them? Feel free to comment about it. Next time is rule #8: Use First Class Collections. Tuesday, January 6. 2009
Deep Simplicity Part 6 Posted by Matthew Purdon
in Software Development at
17:12
Comments (0) Trackbacks (0) Deep Simplicity Part 6
The next rule in Deep Simplicity is Keep All Entities Small. This is one of the rules that I think should be more of a guideline. Jeff Bay thinks that a class should be no more than fifty lines. I think adding the corollary that it's fifty lines without comments makes this rule a little more palatable.
That being said, Jeff does have some good reasons for limiting the class size. The first reason is that classes that are more than fifty lines long tend to do more than one thing - which is bad because it makes them harder to understand and harder to reuse. Another good point is that a class that is small is going to fit onto your screen without scrolling, being able to see as much of it as possible means that it is easier to grasp all of the responsibilities of the class. That's it for this one, next time we'll talk about rule #7: Don't Use Any Classes with More Than Two Instance Variables Monday, January 5. 2009
Deep Simplicity Part 5 Posted by Matthew Purdon
in Software Development at
19:24
Comments (0) Trackbacks (0) Deep Simplicity Part 5
The next rule we will be looking at in Deep Simplicity is Do not abbreviate. As developers, it is often said - tongue in cheek - that being lazy is a virtue. I think that the laziness of developers is a key source of preventable errors. Copying and and pasting code being the number one offense when it comes to inadvertently adding errors from being lazy. It's even worse for those developers that are reluctant to use an IDE and hack away on vi or emacs. Another way developers are lazy is by shortening the names of classes, methods and variables with abbreviations which lead to confusion and tend to hide larger issues.
I recently came across code that looked like this: Can any one tell me what a Bwid is? Oh sure you can guess by looking at the context in which it is being used, but are you really sure? look at the amount of energy you'd have to expend just to write this code in the first place. Even if you wrote both the Foo class and the Widget class, I'd bet that you would have to look up the method you wanted to use. If not immediately, a year after you wrote them you'd be screwed. How much more digging would a new developer to the code base have to do? By looking at the reasons for the abbreviation you can find ways to improve the code. Are you typing the same word repeatedly? You probably should look for duplicated code. Are you doing it because the method names you are using are getting too long? You probably should look for a missing class. Try to keep names to one or two words, this doesn't count for PHP classes that have to bear the weight of namespacing. Zend_Cache_Backend_Memcache is okay, Zend_Cache_Backend_StoreDataOnYourHardDrive is not so great. you should also try to avoid duplicating context. If you have a class named Order, naming a method shipOrder is pointless and sounds weird when you say it out loud: $order->shipOrder(). Naming the method ship(), sounds much better: $order->ship(). Keep things simple and clear and you should be fine. If in doubt, try saying it out loud. Next is part #6: Keep all entities small. Saturday, January 3. 2009
Deep Simplicity Part 4 Posted by Matthew Purdon
in Software Development at
19:24
Comments (0) Trackbacks (0) Deep Simplicity Part 4
The next rule in Deep Simplicity is based on the Law of Demeter ("talk only to your friends") but is phrased more colloquially as Use only one -> per line. In PHP it should actually be "Don't use more than two -> per line" since we have to use $this-> in order to access local properties. The main reason we want to try to follow this rule is because if we don't, we are breaking a basic principal of OOP - encapsulation.
By reaching into the child of a child object, we are essentially saying that the child object is a middle-man that does not provide us with the functionality we need. It can also be an indication that there is a missing object in our Domain. By treating code that looks like this $a->b->c() as a warning flag, you can be on the look out for objects and classes that may be missing. Let's take a look at some code and then we can see if we can make it better. As you can see, we are reaching far into the account's dirty bits to put together the balance for the User. To me, the code felt bad as soon as I wrote it. To be completely honest, it's actually the for loop that is bugging me. Other than this example, it has probably been over a year since I used the for keyword. Lemme just fix it up a bit before we continue. Although this code is much improved over the previous version, we are still reaching into transactions to get their amount. This is bad. To be completely honest, the User object should have no knowledge of the concept of a transaction at all. When you go to the bank machine you choose to withdraw $100 from your checking account. My bank machines don't offer the "Add withdrawal transaction to your checking account's list of transactions" option, does yours?. After you get your cash monies, you are presented with a receipt, on which is printed your checking account balance, not a sum of your transactions. So, let's write it like that: I know right? Have you noticed how many times in this series when we are done we end up with methods that are less than five lines long? Although the User class API is essentially the same, we have improved the Account class API by adding the getBalance method to it. This method has a strong cohesive name and responsibility. This means that other developers are far more likely to use it and the line $this->account->transactions[$i]->amount() should be rarely seen in the Domain if at all. Next part is #5: Do not abbreviate. Saturday, January 3. 2009
Deep Simplicity Part 3 Posted by Matthew Purdon
in Software Development at
08:40
Comments (0) Trackbacks (0) Deep Simplicity Part 3
The next rule is one that I think is vitally important to the PHP community: Wrap all Primitives and Strings.
I think there are two reasons that PHP developers struggle to grasp the concepts of Domain Modeling. Both are related to the PHP language itself. The first is that I think many, if not most, PHP developers start out with procedural programing and then move on to object-orientated development. The second is the concept that many object orientated languages have that "everything is an object". In PHP nothing is really an object. As a result, PHP developers tend to think of everything in terms of arrays. This prevents them from making the fundamental leap from simple OOP to Domain Model development, which means that you break everything down into objects with distinct responsibilities and well-defined relationships. A key way to start thinking in objects is to literally try to make everything an object. I find many PHP developers are afraid of objects. They often avoid them by using the excuse that they are "slow", this of course it total crap. Objects have been plenty fast ever since PHP 5 came out - years ago now. Okay, let's get to some code. Our example this time will be a simple function that takes hours, minutes and seconds and converts them into number of elapsed seconds. Although this example is very contrived, it is a valid problem to be solved. The key to writing bug-free code is to make sure that you make no assumptions about the data you are processing. We have to verify that the provided values are valid for numeric processing, because we are dealing with simple scalar values we must ensure that we are not assuming that the variables are positive integers. The code in the previous example is made more semantically clear by the naming of the function arguments as $hours, $minutes, $seconds but what if they were named $a, $b, $c? Without commenting, we would need to assume that the value in $a was indeed hours. If someone passed in the values in an incorrect order, we then have a difficult to debug problem. By wrapping our scalar values in a simple Value Object, we end up with a much simpler function free from dangerous assumptions: As you can see, we once again have drastically reduced the complexity of the solution to our problem. In the end, we have no assumptions left as the interpreter is going to guarantee that the parameters are passed in the correct order, even without type hinting we are not tripped up by the variables being named $a, $b and $c since we are only performing simple addtion in our method. Next time we look at rule #4: Use only one -> per line. Wednesday, December 31. 2008Deep Simplicity Part 2
Okay, here's a breakdown of the next rule: Don't use the else keyword.
Although there is nothing wrong with the else keyword itself, there are two forms of abuse that drastically reduce your code readability. The first is too much code in each of the branches which makes it hard to determine where you are in your branches. I remember when I first started coding I found that once I scrolled to the next page after the initial if / else I had a hard time determining whether the closing brace I was looking at belonged to a for loop, an if block or what. My solution at the time was to put little comments at the end of the braces like this:It didn't seem so bad to me at the time since I was also playing around with bash a lot and it kinda looked the same. After a while though I got sick of typing them. I think the real reason I stopped adding them was that I learned to take the pages of code and turn them into functions so that the "end" comments seemed silly.If you get lost trying to follow the branches in that chunk of code, you have chosen the wrong career. The end comments were dropped. For simple if/else conditions, I now choose to set a default and use return to skip processing more than I should. So instead of something like this:I would now drop the else entirely:Could just be a style thing, but the second version seems like so much less work to read... *shrug* The other way that if/else blocks can get nasty is if you have crazy nesting action. Of course you should never have that situation if you followed the first rule. hehe. One of the key ways to handle logic in a more OO way is to employ the strategy pattern. I know, I know. Patterns are the devil! Patterns are for n00bs! Would you prefer that I say you should use polymorphism to change the internal implementation of a method at run-time? Seriously though, get over yourself. So let's say that we are going to process credit cards, there is special handling for each of the card types we want to process: Amex, Visa and Mastercard. Here is some code that might do this:Believe it or not, I have actually seen this code out in the real world. It is definitely hard on the eyes, and it's only got three credit card types in it. The original code also processed Diners, Discover, JCB and EnRoute. I especially love the mixed switch and if action. So sexy! Here's what the code *could* have looked like if the author had broken out each strategy for determining the card type based on the card type itself:I am not going to show you the details of the *CreditCardType classes as they should be pretty trivial to write. Just take all of the junk related to validating each card type and stick it in the matches method. So simple! Although the code in the getByCardNumber method is much simpler (almost 1/3 the size) it can easily be extended to handle any number of card types by simple appending the new card type to the array of names and by adding the appropriate type class. Believe it or not I actually rewrote this code after my first draft to make it more English-like. Line #8 of the last example used to read "if ($validator->validates()) {" - whatever that means. Heck if you really wanted to get fancy you could use a directory iterator and not bother with a hard-coded list at all. Long story short, try to keep your logic branching from getting out of control. It doesn't do anything to make your code better. Next post will be rule #3: Wrap all primitives and strings. Monday, December 29. 2008
Deep Simplicity Posted by Matthew Purdon
in Software Development at
12:23
Comments (0) Trackbacks (0) Deep Simplicity
So, I am a huge fan of ThoughtWorks. I really think that the crew over there are on the edge of everything I strive to be as a good developer. Many of the software development best practices are pioneered by people like Martin Fowler that work there. I recently picked up the book The ThoughtWorks Anthology and was impressed by many of the articles. Probably my favorite was the the one written by Jeff Bay titled "Object Calisthenics." He talks about 9 steps to better software design through a concept called "Deep Simplicity", and I like them. A lot.
1. Use only one level of indentation per method 2. Don't use the else keyword 3. Wrap all primitives and strings 4. Use only one dot (-> in PHP) per line 5. Don't abbreviate 6. Keep all entities small 7. Don't use any classes with more than two instance variables 8. Use first-class collections 9. Don't use any getters/setters/properties Holy cow, I bet some of you are freaking out already! Don't use getters or setters?!?!?! Don't use more than two instance variables per class? Impossible! Although I am not sure you have to comply to these rules 100%, I think keeping them in mind when developing is going to help you write better code. I recently posed the following chunk of code to a co-worker: I then asked him to "make it better". He ended up with the same basic loop just with less lines. I then showed him the code that I had written for the same chunk of code. Now, as I often say, there is no such thing as "the right way" to solve a problem. I do feel that the solution I came up with is better, the improvements being garnered through applying rule #1: one level of indentation. In fact, I only indented once in the check to see if the $limit value was valid. Everything else is at the default indentation style for class methods. What we got as a result was an improved API that allows a consumer to get all widgets, all widgets that are in stock or a limited number of widgets that are in stock, which was the original requirement. We also get a completely reusable filter object that can accept a list of anything as long as the objects in the list implement the isInStock() method. Next post will be about rule #2: Don't use the else keyword. Wednesday, November 5. 2008Back to Linux
So I have been debating for a while now whether I should buy a Mac or not. I see a TON of developers starting to move to that platform and to be honest, I really like how things really just work on a Mac. The problem is that I run triple head, which means that I have three monitors connected to my PC. I really enjoy having three monitors and I feel that the extra cost is actually warranted in terms of my productivity. It's not that there is a tangible gain in lines of code produced, it's just that I am less annoyed or distracted while I work. Since I put in about 55 hours every week minimum, being less annoyed helps me stay more motivated.
The problem with Mac, is that they are crazy expensive. Not like a few hundred or even a thousand dollars, like three times as expensive. Here's the specs on the box I just built: CPU: Intel E8500 Core 2 Duo @ 3.16 GHz ($200, Great processor, overclocks like a dream) I also bought a copy of Windows XP, because I am an adult now and don't have time to bother cracking that crap. Besides, it doesn't take long at my current rate to mean that not spending the $160 on windows woudl end up actually costing me more in time. The system kicks ass! In SLi with a mere 10% overclock (They got a similar system to 40% overclock on tomshardware.com) I got a 3DMark06 score of 21,306. Well above the average score of 11,000. All for the low-low price of $1560. I know, you could get it a lot cheaper off of NewEgg.com, but they don't ship to Canada. Jerks. Now, try to get something even remotely similar in a Mac. Even used from Craigslist if you want. I hope you have like 6Gs because you can't buy a Mac etch-a-sketch for less than $3,000. So, long story short I didn't want to throw away money to Apple but I wanted to have a damned shell again. I installed Ubuntu to dual boot with windows and haven't been happier. I can drop back to Windoze to play my First Person Shooters and reboot into Linux for work. By sharing folders for things like Thunderbird, I can keep everything in sync without much hassle. Oh, and you don't mind rebooting when it only takes 46 seconds for windows to go from off and dead cold to fully loaded and ready to play. Did I mention I love my VelociRaptor? I really, really do. Friday, September 12. 2008Debugging with FirePHP
One of the nicest features to have when you are developing an application is a decent debug console so that you can see what your application is doing without having to look through ten log files and put var_dumps that you have to comment out all through your code. In the Zend Framework v1.6 we get a new feature based on FirePHP which will allow us to log directly to the Firebug console with a simple API call from PHP. Here is an example of how this looks in my application:
Continue reading "Debugging with FirePHP"Wednesday, September 10. 2008
Better Alternatives to using ... Posted by Matthew Purdon
in PHP at
14:21
Comments (0) Trackbacks (0) Better Alternatives to using Zend_Registry
Don't get me wrong, I think the Zend_Registry component is great. There are a couple of problems that I see when using the Zend_Registry as a container for junk like database connection objects and session namespaces and pretty much every other resource that you need to be globally accessible. The first, is that there is no information about what kinds of resources are available to you when you are using the registry. In other words, there is no way to know what Zend_Registry::get('db'); is actually going to give you. Is it a Database connection resource or is it a Data Buffer? Actually, it almost makes more sense for "db" to be an acronym for data buffer ... At any rate, there is no way to enforce what you are getting. This means that your editor can't code hint for you and your API docs don't really show an object that has the responsibility of wrangling application resources. I guess that is a good summary for the first issue with Zend_Registry - it's too generic to be really useful.
The second problem with the Zend_Registry is that it is essentially a global array. At any given time an innocent developer can unwittingly blow away your database connection with his data buffer and there is nothing to stop him. We all know (or should know) that global variables are bad. They inject uncertainty into our applications and can be the cause of some of the most irritating to debug problems. So, to sum up the second issue with Zend_Registry - it suffers from the same issues that all global variables suffer. So, how do we fix it. Simple really, we create an object that is responsible for maintaining these application services. In fact, I use two different objects to manage two different types of application resource. I use Naked_App_Environment to manage configuration and environment information and I use Naked_App_Workspace to manage my application resources such as Naked_Db connections and Zend_Logger instances. Let's take a look at these two components and see how your life as a developer can be made better... Continue reading "Better Alternatives to using Zend_Registry" Friday, September 5. 2008
A day with Google Chrome Posted by Matthew Purdon
in Technology at
09:22
Comments (0) Trackbacks (0) A day with Google Chrome
So I installed Google Chrome yesterday. After spending an hour or so gloating to the developers that work on a Mac because they couldn't install it I sat down to really play with it. I heard a lot of people saying things like "Safari has draggable tabs" or whatever as if it was a bad thing that Google implemented them. Ummm, weren't you paying attention? Google intentionally copied good features from other browsers; not only that, but they want other browsers to copy things from their browser so they made it open source.
You know, in the industry we hear all the time about the war between Microsoft and Google. I will admit that I always thought that there was a stand-off between the two as well. After downloading the beta of Chrome I can honestly say that there is no competition, at least not from Microsoft... I can't remember the last time I installed any software beta or otherwise that I was happy to use. (Oh not you calc, you still do a great job) There is honestly nothing wrong with Chrome that I could see. I starts up and renders wicked fast, stays out of the way of what I am trying to do and has some handy features that I already enjoy using immensely. That being said, I haven't gone so far as to make Chrome my default browser yet. Firefox has one major feature that I just can't let go of: extensions. Even though Chrome has some handy items for debugging and stuff, it can't touch Firebug and Web developer extensions for Firefox. Let's face it, the user base for Firefox started out with the geeks and then moved into mainstream as we all recommended it to our mothers so we would stop getting called about their computer acting slow after they went to the recipesthatp0wnyou.com website. Until Chrome becomes a development tool as essential as Firefox is, I don't think it will replace Firefox for me as my default browser. PS: The guy that though of the application shortcuts feature needs a raise. GMail feels like a desktop application now. |
QuicksearchCategoriesBlog Administration |