HOME     SITEMAP     RSS     TWITTER     EMAIL    
Search:   

FollowSteph Follow Steph as he posts Blog Blazer Friday
 
 

How to Write Maintainable Code

The Core: Finch

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:

Write your code from the perspective of
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.

Hackers Movie

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 TableModels. 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.

Office Space Movie

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.



 
Like this article?

Comments:

  •     Average Midget
    · July 10th, 2008  · 8:18 pm  · Permalink

    I’ll give it a shot…

    1) “The Core”, a 2003 Sci-Fi movie.
    2) “Hackers”, a 1995 thriller.
    3) “Office Space”, a 1999 comedy.

    Honestly, I would not have even come close to getting the first one, had it not been for the image name. If I’m not disqualified for cheating, by looking at the file names, I look forward to reading your e-book.

  •     Arjan`s World » LINKBLOG for July 11, 2008
    · July 11th, 2008  · 3:43 pm  · Permalink

    […] FollowSteph.com – How to Write Maintainable Code ‘ Write your code from the perspective of the person who’s going to use it ‘ Sounds so simple but we forget […]

  •     Joske Vermeulen
    · July 11th, 2008  · 4:28 pm  · Permalink

    Awww just too late to type in the label you see when you hover the mouse over the image 🙂

    I would have guessed wrong on the second one (would have said Swordfish) and I wouldn’t even have known where to start for the first one. Last one is easy.

  •     Steph
    · July 13th, 2008  · 4:09 pm  · Permalink

    Hi Average Midget,

    Firstly let me say congrats on winning your copy of How to Generate Traffic to Your Website!

    And no you didn’t cheat, it was my mistake for leaving in that information. If anything, I have to give you kudos for figuring it out this way 🙂

    I’ve just sent you the ebook a minute ago by email. Don’t be shy to let me know what you think of the book when you’re done reading it.

  •     Steph
    · July 13th, 2008  · 4:13 pm  · Permalink

    Hi Joske,

    I kinda figured the first one would be the hardest by far. Although a lot of people have seen the movie, few people seem to remember his hacking abilities.

    For the second one, it all depends on how long you’ve been into computer related movies. It’s an oldie but a goldie. I still get a kick out of the “prototype pentium” chip that Acid Burn’s laptop had 😉 Technology evolves so fast!

  •     Ngu Hui
    · July 14th, 2008  · 12:20 am  · Permalink

    Speaking about writing maintainable code, doesn’t it occur to you that writing maintainable can be harmful?
    https://itscommonsensestupid.blogspot.com/2007/11/smelly-code.html

  •     Steph
    · July 16th, 2008  · 10:45 am  · Permalink

    Hi Ngu,

    I actually remember having read your post before. It’s very good and unfortunately it happens way too often!

  •     Day 49 - Message In A Bottle... | The Recursive ISV
    · July 28th, 2008  · 11:14 am  · Permalink

    […] wins the day.  Steph has a fantastic article in his blog on exactly this kind of idea, titled How To Write Maintainable Code.  It’s worth the read.  Please do read it and return […]

  •     Day 49 – Message In A Bottle…
    · March 27th, 2010  · 9:03 pm  · Permalink

    […] wins the day.  Steph has a fantastic article in his blog on exactly this kind of idea, titled How To Write Maintainable Code.  It’s worth the read.  Please do read it and return […]

Write a reply:





 


SOFTWARE AND BOOKS BY STEPHANE GRENIER:

LandlordMax Property Management Software

LandlordMax is the EASIEST
Property Management
Software available!
Try it for free!

Real Estate Pigeon

Real Estate Pigeon
The place to ask and answer
all your real estate questions

Blog Blazers: 40 Top Bloggers Share Their Secrets to Creating a High-Profile, High-Traffic, and High-Profit Blog!

Blog Blazers is a book that
features secrets from the
Top 40 Bloggers on the web

How to Generate Traffic to Your Website ebook

How to Generate Traffic to
Your Website
is an ebook for
to you achieve success


 

FollowSteph
More resources from Stephane Grenier:
PUBLICATIONS
For people who work on the web
Blog Blazers
How to Generate Traffic to Your Website
 
SOFTWARE
The EASIEST Property Management Software available!
LandlordMax


Copyright @2003-2024
LandlordMax Property Management Software

Disclaimer: This is a personal blog about my thoughts, experiences and ideas. The contents of this blog are for informational purposes only. No content should be construed as financial, business, personal, or any other type of advice. Commenters, advertisers and linked sites are entirely responsible for their own content and do not represent the views of myself. All decisions involve risks and results are not guaranteed. Always do your own research, due diligence, and consult your own professional advisors before making any decision. This blog (including myself) assumes no liability with regard to results based on use of information from this blog. If this blog contains any errors, misrepresentations, or omissions, please contact me or leave a comment to have the content corrected.