How To Quickly Setup a Software Development Environment
At one time or another all software developers have joined a project or team where the development was already underway. The most common introduction for a new developer to these projects is to setup their development environment. If you’re extremely lucky, a lot of this work is already done within the corporate disk image, but more often than not it’s up to you. This is especially true if you’re a contractor.
For a typical Java project, the story goes something like this. Download and install a specific JDK (Java Development Kit). Download and install a particular IDE like Eclipse. Download and install a specific web server. By the way, depending on the company, some of these versions may no longer be available which means you have to track down someone who still has an available copy somewhere. But assuming they’re all the latest versions, that’s just the start.
Once that’s done, you have the core applications to setup. Then you get to start downloading and installing the support applications. If you’re using Eclipse, maybe it’s the SVN (Subversion) subclipse plugin or the TortoiseSVN client. A good text editor such as UltraEdit. FireFox. The list goes on for about a dozen or so applications.
After that you probably need to configure your system settings. Most likely you then have to set up some development environment variables or configurations (server.xml, eclipse.ini, etc.). Save some connection settings in Putty. Setup some network drive connections. And on it goes.
But the fun doesn’t stop there! At this point you’ve just got your environment setup, you haven’t downloaded the project’s source code. Now you need to checkout the project from the source. Once that’s done you need to run the automated build system to get the project up and ready on your box, perhaps using Ant or Maven. If you’re lucky, and the company was in the upper technological echelon it ends there. Unfortunately most companies don’t completely automated their builds so you often still need to do some extra manual tweaking to get your project running. And on it continues.
Which means that all new developers lose anywhere from a few hours to several days setting up and configuring their development environments. Very expensive! And the longer your project goes (there will be some developer turnover with time) and the bigger your team gets, the more expensive it gets. Plus, with time this knowledge will disappear. People will forget steps, or why things are done in a certain way. Which means that at some point setting up a new project will be, well, for lack of better word, insanely difficult. You’ll have to track down specific people within the project because they’re the only ones left who know anything about certain parts of the system. If you’re really unlucky, the only way to get up and running might be to you copy the complete environment from one computer to the other. Yes complete copies of directories! It can become a mess.
The good news is that there’s a much much better alternative. One that will make everyone’s life much easier, and keep the knowledge over time. Can it really be? Yes, we don’t all have to suffer through this. And what’s even better is that I’ve implemented what I’m about to suggest with great success several times, and not just at LandlordMax but also at companies I’ve consulted for in the past.
Create a developer’s installer!
Why should your final product be the only system with a deployment strategy? Why not create one for your developer environment as well. Especially if your company doesn’t have a fully pre-prepared disk image ready with everything (which is virtually guaranteed).
How hard is this to do? It’s actually extremely simple, simpler than you might think. If you’re company already owns an installer like Install4J (which I’ve recommend in the past), then it’s a matter of an hour of someone’s time. And it shouldn’t just be kept on someone’s machine, it should be it’s own full project within your version control system. This way if any developer does any environment change, it’s up to them to update the developer installer project. This includes if an application needs to get updated (for example to the latest version of Eclipse, the latest version of FireFox, etc.). This isn’t just limited to new software updated, but also configuration changes, etc. No longer do you need to keep a record of configuration change emails, it’s all done for you in the developer installer!
Therefore when a new developer starts, all you have to do is get the latest executable build, copy it on a USB key (network drive, whatever), and let them run it. Better yet, you can do it the day before they come if they’re going to use in-house hardware. During this time you can walk them around and introduce them to the rest of the people they’ll be working with, explain them the project in more detail, or any other higher value action items you may have.
And don’t worry if your company hasn’t bought a great installer building tool like Install4J, you can also use the open source installer creation system called NSIS. Up until LandlordMax, I generally relied on NSIS to create Developer Installers since I could never guarantee what was available in the different development environments, but with LandlordMax we use Install4J. Both are great, the main difference is that with NSIS it will take you a lot longer and you’ll need to acquire a lot of specific NSIS knowledge (it’s a scripting language). So instead of an hour or so for Install4J, expect it to take a few days to a week or more with NSIS to build a good installer. But even if it takes a week, it’s worth it!!! The good news is that it doesn’t have to be production quality, just beta quality. In other words, you don’t have to include all the checks like in a production installer, you can assume that your users are pretty smart and will mostly enter in valid values (for example you can assume there’s enough disk space on the hard disk, that it exists, that’s writable, and so on).
The good news is that an NSIS installer script shouldn’t be more than a few dozen lines to a couple hundred lines (assuming you’re using functions and macros available on their website). So that’s not too bad overall. With Install4J it’s all GUI based, and the resulting script is stored in an xml file which can be called from any Ant build script! The cost to benefit ratio for one person to translate all the developer environment knowledge into an automated installer for everyone that will be available forever is unbeatable!!
A few quick tips:
- Don’t re-create your main build file (Ant or Maven in Java), leverage what’s already there. In other words, you developer installer can call the main build file in your project to complete the environment setuo.
- Use silent installers. Most applications have silent install options, so use them. The less interaction your developer installer requires the better.
- Give the developer the option of selecting the initial install location.
- As part of the install, leave all the individual installers within the main install directory (for example leave the FireFox setup executable somewhere in the install path so that it can be run separately later).
- Give the option to select which “modules” to install. For example give the option to install FireFox, to install Eclipse, to configure the server.xml configuration file, etc. I’ve done this in the past by presenting a list of options (checkboxes) the user could select. By default all are selected with a toggle to unselect all of them near the bottom.
- Assume advanced users are using your installer. In other words, you don’t need to spend too much time on checking for user errors. Let it fail miserably if there’s an error. It’s not worth the time.
As an added benefits, everyone has the same development environment initially by default. With time some developers will deviate from the standard development environment to what they like, but it’s good to start the same way. At least this way you have a default method to setup a developer environment which is a million times better than having a bunch of different developers setting up your environment in slightly different and unique ways. Plus if there’s an issue, it’s REPRODUCIBLE!
Permalink to this article Discussions (6)
What's the Real Value of a Guarantee/Warranty?
Not all guarantees and warranties are worth the same. For example here at LandlordMax we guarantee that we will give you a refund within 30 days of buying LandlordMax if your not completely satisfied (remember this is after trying it for free for 30 days before purchasing it). We’ve honored this guarantee every single time!
However not all companies create guarantees with the intentions of honoring them. And even those that do might not (especially if money starts to get tight). Let me start with an example of a useless guarantee (sometimes also called a warranty – we’ll assume for this post that they are the same although there are minor differences). A year ago I bought a dehumidifier for my house, a Honeywell. With the dehumidifier came a 5 year guarantee. If anything was to go wrong, they would immediately replace the unit. All I had to do was call the 800 number listed in very large and bold letters on the box, in the manual, and so on.
As you can guess, the dehumidifier broke before the guarantee was up. It actually broke within a year, less than 20% of it’s guaranteed lifespan. So I obviously called the big bold number listed everywhere that had influenced my purchasing decision. On a side note, I ended up buying two units, one for our house and one for my mom’s house. Both units stopped working within a year, so I suspect there are some production issues.
In any case, after calling the number I discovered that Honeywell itself doesn’t actually manage the guarantees, they’ve outsourced that to another company. Not a big deal, but if you’re going to outsource it’s important to make sure the company that you use to outsource does a good job and represents you well. Turns out that the company they outsourced for was no longer around. But they gave us another number to another to call so that we could take advantage of the guarantee.
Again I took the phone and made a call so that I could exercise the guarantee. And in this second case, the company is pretty much clueless. They don’t really know what to do, so they take my name and phone number and promise to call back within a few days with some answers. Of course being busy as I am I forgot to follow-up within a few days, and I ended up calling a few weeks later. Still the same response, we’ll call you in a few days. Nothing again. It’s as if no one’s there. And this wasn’t just me, my mother, with her faulty unit, also had an identical experience.
It’s almost as though they’re trying to ignore us hoping that the problem will go away. And it did, we both eventually gave up and got ourselves other different units. But rest assured it wasn’t from Honeywell, it was from another brand. I’ll never buy another Honeywell dehumidifier again. Even though my experience with their home thermostat has been very positive this experience has really soured me on their company. I now place absolutely no value in their guaranties and warranties. They just don’t honor them. Getting rid of their obligations through attrition is very deplorable!
But who’s going to go after them to enforce the guarantee. I need a replacement now, not much later. And I’m for sure not going to spend my time chasing down a few hundred dollars that will likely never come when I could make multiples of that working on my business. So they’ve just basically got the benefits (increase in sales conversions) from their guarantee without having to enforce it. Maybe it’s different with other departments within the company, but for this dehumidifier unit they definitely own up to their claim.
The moral of this story is be careful when you make a purchasing decision, especially if you put a lot of value on the guarantee or warranty. Don’t just assume it will be honored. Look at who you’re buying from and see if they have a history of owning up to their guarantee. Check their reputation. And only then put value into the warranty.
And one last thing, the longer the duration of the warranty, the less value you should put on it. For example, the odds of a lifetime warranty being honored after 20+ years of purchase are pretty low. They’re assuming you’ll have moved on, lost your receipts, there is no equivalent replacement unit, or maybe even that the company might not be there anymore. I personally won’t trust anything beyond a 5 year guarantee, and even than my trust is limited. For example you can be pretty confident that most car manufacturers will honor their warranties. But I wouldn’t put any weight in a $40 coffee maker 20 year guarantee. And is it even worth your time to follow through with a $40 guarantee after 15 years…
Permalink to this article Discussions (0)
LandlordMax Customer Testimonial
“I’ve loaded LandlordMax and played around a bit, and just want to tell you that you are now my hero.
I wanted to get it going a little bit so I knew how to teach our property manager. Hands down, this is the easiest and most uncomplicated property management program I’ve ever seen – especially for us, since we are a small property.
I’ll definitely let you know if I can’t figure something out, but wow, this is wonderfully user-friendly.
Big thumbs up, and thank you!”
Permalink to this article Discussions (0)
How do You Add Empty Lines in WordPress Posts?
Does anyone know how to consistently add blank or empty lines within a WordPress post? Seems like such a common and simple thing but for the life of me I can’t figure it out. And I’m not the only person struggling with this issue. If you do a quick Google search, you’ll find many people asking this same question.
How can this have been missed? Almost everyone wants to add empty or blank lines to format their text. Often you need to add a little bit of white space to make the post look clean. But in WordPress it seems like they’ve gone to the ends of the world to make this an impossible and death defying feat! I just don’t get it.
If you enter in blank lines in the WYSIWYG editor, as soon as you click on the save or publish button, all the empty lines disappear. All your text gets crunched up again. Type them back in and save. Poof! Like magic, gone. What’s up with that?
What about manually coding them in the html view you ask, which by the way is wrong since the goal of WordPress WYSIWYG editor is to abstract this html knowledge out of your daily repertoire (you shouldn’t need to know html to be a blogger, although it really really helps). No can do. I’ve tried everything! I’ve tried <br> statements. I’ve tried <br> </br>. I’ve tried <p></p>, <p> </p>. I’ve tried everything and nothing works. As soon as you hit the save or publish button, that code disappears into the never land.
So how does one add an empty line in a WordPress post? I have no idea. You could try looking for support on WordPress.org or support on WordPress.com, but neither has a consistent solution. The only somewhat related solution someone’s found is to increase your paragraph spacing in CSS (Cascading Style Sheets) which is not the solution I’m looking for. I want empty lines, between images, between paragraphs and images, in other words any block of content. A simple request you would think.
How can this be so difficult? If I’m struggling with this others have to be too. My big question is why? It seems like such a common thing that I just can’t but ask how this could be such a difficult task. Does anyone know of a consistent solution?
Permalink to this article Discussions (83)
The Secret to Making ANY Computer Safe
Have you ever been at someone else’s house and needed to use their computer to quickly check something on the internet but where worried about the security of their system? If it was infected with viruses, spyware, or what have you? What about using your credit card to buy something. What if you’re on vacation and needed to use it for business purposes, or just to quickly check something within your bank account?
I can tell you that this completely terrifies me. I’ve seen way too many computers completely infected with garbage. Computers that I wouldn’t even do anything at all on, not even save a text document for fear of keystroke loggers.
Yes it can be that bad! Less than a year ago I was at a someone’s house where the computer was still running Windows 98. It had no router, not even a software firewall. No antivirus. Nothing. Connected directly to a broadband modem. This person was complaining that their computer was really slow and kept crashing all the time. And I mean all the time! When I asked them about even just upgrading the OS, I got some funny looks, which is when I realized it wasn’t even worth asking about a firewall router. It’s a good thing I didn’t need to use his computer to connect to the internet. I can’t even begin to imagine all the possible harm I could have self-inflicted!
Although this is a more extreme case, it’s not that extreme. Another person I know was using an older version of Windows XP, not even SP1. They couldn’t be bothered to upgrade. No router, nothing. Direct connection to a broadband modem. As you can imagine the computer was pretty much useless, but they kept using it thinking the computer hardware was the issue. They even did their banking on it!!!
As a quick divergence, a lot of people are heralding the Mac as the solution to their security and performance issues. But that’s completely false, you’ll still encounter the same issues. Like everything new, there are less issues right now because if you buy a Mac right now you’re fairly up to date (plus there haven’t been as many targeted attacks yet). But wait another year or two as these people don’t update their operating system like they should. Especially if they also connect directly to broadband modem boxes. It’s only a matter of time before all these brand new shinny macs also start to come to a crawl.
The fundamental issue is not the OS but the people. And it’s not that they’re idiots filling ID-10-T forms all day, it’s that they don’t know any better. Upgrading and security hasn’t been ingrained in their brains. They hear about it, but they don’t really get it, at least not yet. Unlike the concept of changing the oil in your car every x miles, upgrading is still not a fully understood benefit. It’s not really appreciated, so many people just don’t do it. Plain and simple.
But getting back to our discussion, what can you do to use any computer to safely access the internet? Two things really. Well technically you could probably get away with one, but just to be extra safe I recommend doing both.
1. Use a Live-CD OS to boot the computer.
For those of you who aren’t familiar with this concept, what it means is that you can create a CD that will boot the operating system from the CD drive. A great example of this, and the one I use, is the Knoppix linux operating system.You can technically do this with a USB key as well, it’s just that not all computers will allow you to boot from the USB key whereas a CD is 100% supported.
What you’re basically doing is bypassing the normal operating system and booting your own safe operating system! This is much better because you can guarantee the OS (operating system) is safe, or as safe as you can make it by always using the latest version.
No longer do you have to worry about a corrupted operating system. Just bring your own on a CD. And the best benefit of all is that there is ZERO installation. It works directly off the CD. It doesn’t touch the computer’s OS in any way. Theoretically you could remove their hard drive and still use the computer! It’s a self-contained OS. You get a guaranteed OS that doesn’t touch the other person’s computer. It doesn’t install anything, heck it doesn’t even need to know which OS they’re using.
But even more than that, you can add one more layer of protection to this setup. But I would only recommend going this far if you’re going to be staying at someone’s place for an extended period of time, otherwise I can’t imagine carrying the device around in my back pocket.
2. Use your own router.
Above bringing your own OS on a CD, why not bring your own router. They can be bought for as little as $40. Not only is it another good line of defense, but it can make the computer much faster as it won’t be busy having to block tons of unwarranted traffic from the net. Let the router do that. Plus two lines of defense are always better than one. It’s just safer.
Conclusion:
With these two tips, bringing your own OS on a CD and your own router, you can virtually use any computer risk free (as long as you boot from the Live-CD!). You won’t have to rely on someone else’s capabilities to keep their system clean. You won’t have to potentially anger/insult/scare anyone by letting them know their computer is filled with viruses and spyware. And you’ll be able to confidently access your bank accounts and any other highly sensitive website worry free.
As one last little bonus, if you bring your own OS on a CD, you’re guaranteeing yourself to always have the same software everywhere. If you prefer FireFox over IE, you don’t have to hope they have it installed, or install it for them as they look behind you all worried with sweat beeds dripping down their forehead asking you over and over, are you sure it’s ok? It will be on your CD everytime all the time.
Permalink to this article Discussions (2)
LandlordMax Customer Testimonial
Nothing makes my day like getting very positive feedback from LandlordMax’ers (people using LandlordMax). Here’s one I recently received from Heather Borquez that I just had to share:
“I love the program! And the update! Keep ’em coming. I am very happy with your program and I run 20 units on this software and find it fantastic. It is easy to keep my receipts and accounting in order with this program. Keep up the good work.”
Thanks Heather, it’s great to hear that Landlord’s property management software is really working for you!
Permalink to this article Discussions (0)
How to Write Maintainable Code
Read Code Complete 2. Read Refactoring. Read Design Patterns. Read The Pragramatic Programmer. Read Concurrent Programming. And any number of other great software programming books.
But more than that, more than any book can teach you, write your code from the perspective of the person who’s going to use it. It’s as simple as that:
the person who’s going to use it.
Yes that simple, but realize that it comes with very large ramifications. It means that you can’t write your code for what’s simplest for you from your current view/layer, it means you have to write what’s simplest for the person who’s going to call your code. You really have to think of how your code will be used from their layer. How would they want to write their code. What’s the least amount of information they’ll need to know.
For example, within LandlordMax we have a report generating framework. Every report passes through this framework because we’re using the DRY principle (Don’t Repeat Yourself). But more than that, if we can we abstract it out so that all the next developer has to think about is how to get the data from the report in the correct object. They don’t need to know how the report screen opens up, how the xml report template is loaded, how the logo/letterhead is loaded onto the report. It’s not important.
When I initially developed this section of the code, I took the stance that the effort on building and maintaining this framework would be a lot less than the cumulative time spent generating reports (we already have over 100 different reports). Therefore I decided to spend more time up front to do it well so that future developers would be able to quickly and efficiently get up to speed. And if it needed documenting, then it was probably too difficult. Need being the keyword! It doesn’t mean I won’t write any documentation, it’s just that it should NOT be needed.
So from here to the end of this post, I’ll walk you through my thought process on how I went ahead and built the reporting framework from the other person’s perspective. I believe that this is the best way to describe what I’m trying to explain. Just saying develop from the other developer’s perspective is easy, but what does that really mean. And by walking through the logical steps I took I think what I’m trying to explain will become much more evident.
But before I begin, let me start by saying this example assumes an OO (Object Oriented) programming language and some knowledge of OO (Object Oriented) design. As well, please note that the application I’m going to use here is a real implementation in a real application. It’s the reporting framework within our product LandlordMax. And because of this, the example is more desktop centric (we only offer a desktop application but this will eventually change).
As I mentioned before, on requirement was that it should be easy for developers to jump in because there are going to be a lot of reports. Therefore our main goal in this example is to create a report printing framework that will be easy for developers to use.
Because the software is a desktop application, and it uses an OO language, the first thing we should do is create a generic panel for our report screens. By this, we’ll divide it up into three sections: one section to select which report to generate, another to enter in data for the report (for example a date range), and one last section to display the report results. Sure we could have put the results on another panel, but for now let’s just go with this UI decision.
Assuming this, the first thing we need to do is create a parent/super class for the report panel, which we’ll call SingleReportPanel
. And any report we create from then on will extend SingleReportPanel
. We’ll take for granted that there’s some code somewhere else to manage all the report panels, which means the developer doesn’t need to worry about this. Or at the very least nothing more than registering the report panels so that the framework knows they exist.
So what does our SingleReportPanel
need to do? Well most likely it needs to generate a title to the report (so that we can select it from a list of reports). It needs to be able to generate a panel to get more data for the report (such as a date range, a tenant from a list of tenants, etc.). And lastly our report needs to be able to display the results. At least for now. So our current implementation of SingleReportPanel
should be:
class abstract SingleReportPanel { public abstract String getReportTitle(); public abstract JPanel getDataJPanel(); public abstract ... generateReport(); }
Notice in this example I don’t show any code that needs to be implemented by the SingleReportPanel
. Not even the private internal methods! We’re implementing this from the other developer’s perspective, We don’t care at this point. We don’t want to see it. It’s unimportant. The less they need to know the better. At this point all of the objects the developer needs to return to the framework are obvious (at least those that we’ve defined to this point – we’ll discuss the generateReport
shortly). Not only that, but because we use a JPanel
as a return object, the other developer can pretty much write any UI code whatsoever and it will work. It’s not at all dependent on having any framework specific knowledge. All UI code works!
Regarding the generateReport
function, what type of return object do you think we should define? In our case, all reports are going to be table based (here’s an example of a generated report). But we also want the option to extend this further in the future.
At this point a lot of developers would start looking into custom structures, custom objects, and so on. Things ranging from HashMaps
to ArrayLists
of ArrayLists
. Perhaps creating a custom Object with attributes and what have you. You name it. Basically specialized structures. However that’s not necessarily what you want to do. In our case, we know we wanted to return a table structure with flexibility. Is there something within the language that already offers that which is standard? With Java you can use TableModel
. This is an interface to table data. It’s not specific to Swing, it can be used in a web application as much as a desktop application. It has all the structures we need, including the ability to name columns, store data, sort the data, and so on. But best of all it’s not custom, it’s a standard library object.
And being a standard library object gives you a lot of advantages. Firstly the learning curve is negliable. You have to assume that all developers know or understand anything within the core language library. What’s more, the potential to leverage open source tools and components goes up exponentially when you use core language libraries! So right off the start you get some great benefits. And don’t forget that as the language is updated, the API’s can become more and more powerful.
As a quick side note, if you were thinking why not just send the database results data back directly (ResultSet
) you’d be wrong for several reasons. Firstly, you’d be sending the responsibility of managing the database connection up and down the layers. You’d also be creating a lot of coupling between the database layer and your presentation layer. You’d be forcing database schema knowledge onto the different layers of your code. You’d also be locking your implementation to a database (what if you decided one day to use webservices, etc.). In other words you’d be breaking almost every OO rule out there.
What about just passing the Data Model Objects back as an array? You’d have a similar problem. What if the report crossed over multiple data model objects such as a tenant and a building. But ignoring that, it means that your reporting framework would need specific rendering information on how to properly display the information.
Therefore the best method is to pass back a TableModel
. Every developer who’s ever worked in Java should know what a TableModel
is. It’s used everywhere from desktop to web applications. In Swing you populate your JTable
‘s with TableModel
s. Even the MyFaces implementation of JSF uses a TableModel
for the table widget for the very same reason. Not only that, but the TableModel
has the ability to pass within it renderers so that your data can look pretty. This is standard functionality within the core libraries.
Knowing all this, if you were to become a new developer at LandlordMax do you think it would be difficult to create a new report? Probably not. All you’d need to do is create a new class file, then extend it from SingleReportPanel
. This would immediately cause a compiler warning, where you the IDE would offer to create the three abstract methods we created above. You’d then be responsible for filling in code such as illustrated below:
public class HowEasyIsThisCodeToImplementReportPanel extends SingleReportPanel { public String getReportTitle() { return "How Easy is this Code to Refactor"; } public JPanel getDataJPanel() { // Standard Swing code. } public TableModel generateReport() { // get data from dataJPanel // call database with data from dataJPanel // add any logic at all (other db calls, massage of data, etc.) // return standard TableModel } }
Please note that the generateReport()
should never directly talk to the database otherwise you’d be coupling your database to the report framework. Rather you should go through another similar layer to communicate with the data storage mechanism. By doing this, you can call a database directly with SQL, you can use an ORM framework such as Hibernate, or you can even communicate with multiple different data storage systems! And for those who don’t like too much abstraction, you’ll notice that it’s very minimal. It’s not layers upon layers of abstraction, the key mechanism here to make this happen is just where you place your code.
I’ve of course omitted a few details, such as how to get the report template file (an XML file) from the system, but this can just as easily be abstracted out as well. Assuming a naming and location convention, you could just create an abstract method such as (I put the return object as a String but this could be easily refactored later):
public abstract String getReportTemplate();
which would return:
public String getReportTemplate() { return "HowEasyIsThisCodeToRefactorReport.xml"; }
The real beauty of this whole design is that it’s fully extensible. You’re not limited by any shortcomings of your thinking when building the framework. It has full the capabilities of being extended beyond anything you can imagine (for examples the data panel could potentially include another complete application!!!). You’re only limited by your imagination.
But most important of all, you don’t need to know anything about the framework!!! The code is simple and easy to read. It uses only standard conventions and libraries. A new person can get up to speed within minutes. Does this code even need to be documented? Any decent programmer can see the SingleReportPanel
abstract class and quickly see what needs to be done. Look again at the class:
class abstract SingleReportPanel { public abstract String getReportTitle(); public abstract JPanel getDataJPanel(); public abstract TableModel generateReport(); }
Do you need to know anything about the internals of the reporting framework. Is it limiting you withing any constraints of the framework? Do you need to know about any custom reporting framework structures, objects, etc.? Does it allow you to extend it with virtually any other system? The simpler you can make the implementation from the other person’s perspective the better!
Did you notice one other thing? I never once talked about how to implement the framework from our perspective. Maybe working with a TableModel
isn’t the best way of working with our reporting framework. Maybe we’ll have to convert this object to a custom reporting framework object. The truth is it doesn’t matter from the other developer’s perspective. Nobody else should have to learn the reporting framework other than you! Why would you want to burden EVERYONE with this knowledge. Do they benefit from it? Unless you hit a performance bottleneck, use standard constructs to pass information back and forth. It’s much much easier for all future developers. And rest assured more time will be spent developing reports than building the reporting framework over the lifetime of the software.
But wait, above that you get a free set of Ginzu knives! But seriously, there’s more. What happens if you change the reporting framework later? Right now at LandlordMax we use JFreeReport. What would happen if we decided to move to Jasper Reports, Crystal Reports, or any other reporting framework? If we didn’t abstract this knowledge and instead forced every single developer to map to the reporting framework’s object/structure, then all our reporting code would need to be re-written if they used another object/structure. And that for every single report! Every developer would then also have to learn this new framework. What a waste of time, there’s no business value to it. You’d never change reporting frameworks no matter how much better the other one might be, the costs would be way too high. And how boring would it be? Do you want to do this for over 100 reports? What about over 200 reports? 1000 reports? The cost goes up and up with time as you add more and more reports to your program.
By using a standard library object, if the reporting component was ever to change all you’d need to do is change how SingleReportPanel
uses the generateReport()
method. No one, and I repeat, no one even needs to know you changed frameworks!
Which brings us back to the original premise of this article, the most important thing you can practice to write maintainable code is to write code from the other’s developer’s perspective. Look at how they will use your library. What’s the best and most productive way for them to use your code? And remember the other developer doesn’t need to be another person, it can just be you at another abstraction layer.
PS: I’ll give away a free copy of my ebook How to Generate Traffic to Your Website to the first person who can correctly name the three movies the pictures on this post come from.
Permalink to this article Discussions (9)
Why You Can't Just Compare Languages With Lines of Code
It’s incredible the number of bloggers comparing one computer programming language to another by just comparing a small snippet of code and saying “See look, I can write this in 5 lines of code where in this other language it takes me 50”. This is especially common for comparisons between languages such as Java versus Ruby (specifically Ruby on Rails versus any J2EE framework).
I hate to be another person adding fuel to this same fire, but I have to speak out. These comparisons just don’t work. It’s not even comparing apples to oranges, it’s comparing apples to liquid nitrogen. There is just no comparison, they’re completely different.
The comparisons are comparing the built-in libraries and not the languages.
The big difference with languages like PHP and Ruby is that a lot of functionality is built into the native libraries whereas Java has more verbose API’s (and it’s been built to handle more than just web applications). But that’s ok, that’s what open source is for. Maybe you can’t just do something like image.rotate(90)
in Java with the native APIs, but nothing prevents you from getting an open source image library that does. There are tons that do. And after you’ve done it once, you’ll always know how to do it. The comparison no longer works.
Again, this is a comparison of the built-in library API’s. Java’s is much more detailed and lower level to allow you more flexibility whereas the others offer the high level functionality for free. Which is better? It depends. In either case, I can take that 50 line implementation in basic Java and extract it to a few lines by using open source libraries. So that’s not a valid comparison. And if you really wanted to push that, then you should also compare what the open source image library offers in terms of image manipulation compared to the other built in language! Again you can’t compare, it just doesn’t work.
The issue with most of the comparison examples is that are too small. A 50 line code snippet doesn’t mean anything. We all talk about how university/college computer science courses don’t really prepare you for the “real world”. Another case in point. A few lines of code doesn’t not represent a real world application.
LandlordMax I built it expecting lots of versions and different people working on the code base. How important is it to get to market first? Personally I don’t think it’s that important. And David from 37Signals really iterates it well in this video, being first is not always a good thing. My company LandlordMax was not the first by far and yet we’re succeeding very well.
Therefore you need to determine where you want to be in a few years. Speed of development is important but it’s not the end all be all. If it is, realize that your growth cost in the following graph will increase exponentially faster. Twitter is being hit by this right now. They burst right out of the gates but right now they’re having problems with that growth. PayPal is also falling apart. I have no doubt that the cost to add new features to PayPal is excruciatingly expensive. We’ve all been part of projects or systems where adding anything, and I mean even the simplest of changes, required extreme efforts. Some systems become unmaintainable.
To understand just how bad code can get, I recommend viewing Alberto Savoia’s presentation at BOS last year. That or visiting TheDailyWTF almost any day.
Scalability (Team Size – NOT Performance)
Everyone seems to talk about scalability in terms of performance, but what about in terms of team growth? If you only have a few developers you can use any language successfully. But as your team size grows some languages don’t scale so well anymore. Ever try to work on a PHP system with a dozen developers? Unless you have, you can’t really appreciate how difficult this can be. With Java, it’s still difficult, but not nearly as much. And it’s not just the tools, certain language lends themselves better to having multiple developers. For example with a dynamic language there are some theoretical limitations on what you can possibly know at compile time within the program. With statically typed languages, there are still limitations, but they’re a lot less. If you don’t know what I’m talking about right here, don’t worry, it’s pretty technical and I’ll discuss this in depth in another post.
I can already hear arguments such as “with Ruby on Rails you’ll never need 10 developers”. I doubt that, but ok, let’s go with that argument. Will they always be the same 10 developers? Not likely. In which case will the replacement developers be able to pick up where the others left off? With dynamically typed languages this is much harder. The IDE’s, because of the theoretical limits, can’t offer the same level of tools and support. For example, because you can’t know for sure of a variable is of a certain type at compile time you can’t provide a tool to drill down into the object within the IDE. This can only be done at runtime.
Another big aspect of dynamic versus static is that it’s very difficult to create refactoring tools in dynamic languages. Again, for the same reasons, because we can’t know the type an object until runtime, most refactorings need to be done by hand with “find/replace string”. This is difficult and very error prone, which is why it’s not often done. And the more refactorings are skipped, the worse they will get with time. Exponentially worse!
Scalability (Code Size)
Another big argument used in comparing programming languages is that one language will take up a fraction of the code base as another. We’ve already alluded to this with the library discussion, where this is not necessarily true (actually I believe it’s not at all true). But in any case, let’s assume it is. Does the language scale up to bigger code bases?
For simple applications it doesn’t matter too much. For example the business logic behind our Free Real Estate Analyzer is pretty minimal. I won’t say there isn’t any, but if you compare it to a normal application for a business (or god forbid an enterprise web application, or even a government application) the business logic is extremely simple. No exception cases, no weird possibilities, no crazy logic. How do these languages scale up for all these cases?
Scalability (Performance)
And of course you have to talk about performance. How do they scale up in terms of actual performance? But notice I put this near the end!!! I don’t think this should be a central theme because all things being equal, the differences aren’t going to make or break the decision unless you expect millions of visitors on a daily basis. And even then you have money for more hardware and smart people to figure out the bottlenecks.
Miscellaneous
What about integrations with other systems? If you’re a contractor and need to work in larger companies you’ll find that most new systems have to integrate with older existing systems. How well does you’re language work with this. Even small businesses have to do this!
What about deployment? If you’re going to be selling it as an application that your customers need to install, can it be easily deployed? For example RoR has some issues with this. Even PHP can be a beast to deploy (think shared hosting). Java also has it’s issues, but if you do it well all you need is a ear/war file.
What about combining the system with other components? For example PHP is problematic if you want to include several open source components because of namespacing. This isn’t necessarily bad, it’s just something you need to be aware of.
What about extensions of the language? For example Java has more open source libraries than any other language. That’s an amazingly powerful asset. You need something that’s not in the language, go find an open source library. And usually there’s more than one great option. RoR is still lacking in this respect, but that’s because it’s still relatively new. I suspect this will change a lot with time.
Conclusion
I guess what I’m trying to say in a very round about way is that you can’t just compare languages directly based on how many lines of code it takes to implement a small task. That’s the worse comparison of all. What you need to do is look at what you’re trying to do as a whole today and tomorrow and base your decision on the factors you find important. Different languages are better for different scenarios.
For example if you need high initial productivity than by all means use a language like PHP or RoR. If you’re only building a one-off application that’s simple and will never grow, use PHP or RoR. But if you’re planning to build a system that will be around for a long time with lots of people passing through it, then use Java. Anywhere in between, well that’s the gray area where either type of language could easily work. It all depends on where you want to go and what you expect the lifespan of your system will be.
Something else I’d like to note, I’m seeing a lot of people getting excited by MVC frameworks in the dynamically typed languages. This is great to see because before there wasn’t really any consistent framework, but it’s still years behind what’s going on in the Java world. MVC frameworks were a great jump forward, and thank you Struts for bringing that mainstream (about 8-9 years ago).
But even now the Java community is looking at alternatives to the MVC frameworks, it’s been found deficient. It’s a great step forward, but it’s not enough. Right now we’re starting to see event based web frameworks such as JSF and GWT really picking up steam. And I’ll be honest, once you’ve tried an event based framework it’s incredibly hard to go back to an MVC framework. It’s just so much more intuitive and powerful. I just hope the other languages start to look at creating new event based frameworks sooner than later. They’re very powerful!
Permalink to this article Discussions (5)
LandlordMax Customer Testimonial
As many of you long time readers know, I like to share some of our LandlordMax’ers customer testimonials on my blog. This week we received one that was succinct yet very powerful from Jonathan Akers of OK! Property Management
“I have to say I am loving the software. Thank you.”
Thank you Jonathan for the compliment, we’re glad to hear you’re loving LandlordMax!
Permalink to this article Discussions (0)
Oops…
As I’ve said time and time again, it’s good to air out all your successes AND failures. And today I’ll be airing out another one of my failures, well more like a mistake. In any case, it’s something that should have been done better.
Yesterday I published the post An Easy Shortcut to Successfully Budget Your Finances. On it I stated a “basic rule” to significantly simplify your budgeting, all the while leaving you with a surplus of money if done right. The rule is sound, but for whatever reason there was a mistake in the translation from my head to my written words (my blog post). It wasn’t a late night post when I was really tired type of mistake, it was written in the middle of the day. It was a classic mistake of my brain saying one thing while my words said another slightly different thing.
Even after re-reading it a few times, it was still perfectly clear in my head. I knew what I meant to say and I had said it. It actually wasn’t until Freewheeler (unfortunately the comment was anonymous) commented on the post that I realized the rules I had written down weren’t exactly what I meant to say. They were close, and I can easily see where I went wrong.
What I wrote was:
AND
For every Expense increase the first digit by 1
Where it should have been:
and reduce all other digits to 0
AND
For every Expense increase the first digit by 1
and reduce all the other digits to 0.
The good news is that the rules I stated would have been even more in your favor, giving you an even bigger surplus. But it would also have made budgeting much harder.
The biggest mistake was on the income, the first digit shouldn’t have been altered, but it made sense in my head. What I meant to say was round down, but what I instead said was round down and then some.
The good news is that my examples showed what I meant to say. The examples are correct, it’s just that the rules weren’t as accurate as they should have been. Good thing they favored the budgeter.
All that to say I apologize for the mistake in yesterday’s post. And it’s been corrected.
Permalink to this article Discussions (2)
NEXT PAGE » |