How to Write an Unmaintainable CMS
Posted by lucidfox.org
at 08:09, 13 November 2008 (UTC)
Everything written below comes from personal experience of maintaining a Java CMS written by our predecessors, who gave us next to no instructions regarding that pile of code.
- Don’t use an ORM library. If someone calls you on it, tell them that there were no ORMs available in 2003. Instead, write your own ad-hoc, bug-ridden object mapping layer that only works with Oracle.
- Don’t use reflection to automatically handle POJO classes being mapped without writing boilerplate code. Instead, ensure that every class has a corresponding DAO class consisting entirely of copy-pasted code to insert, fetch, and update database records on the JDBC and SQL level.
- As such, for every new database table, add three new classes and two interfaces.
- In the base class for all those, use a primary key field of type
Object. Ensure that it can really meanBigDecimal,Long, orIntegerdepending on the context, even for the same class, so to actually get the number value of the primary key, you have to write something likeLong.valueOf(obj.getPK().toString()). - Pass all data in non-generic Lists (admittedly, generics weren’t invented yet) without any comments about what type these Lists actually contain.
- Ensure that the core CMS library, the individual websites, and the utility application used for copying the database between hosts all use different technologies. For bonus points, make the utility application use pure JDBC on the lowest level possible.
- Use a helper library written by your predecessors whose source code is lost, so your successors will have to decompile it first.
- Depend on an application framework but never use its core features, rather only helper classes and tag libraries.
- In JSPs, use nondescriptive names for temporary variables holding objects being rendered, such as “obj” or “list”.
- Instead of using the traditional MVC pattern and letting the controller select the view, link to JSPs and let these JSPs call “pseudo-controller” classes that do all the parameter processing and redirection.
- Start the name of such a pseudo-controller class with an arbitrary letter combination and ensure that nobody knows what it means (such as “PL”). Give all instances of these classes an identical and equally arbitrary name (such as “UC”).
- In said pseudo-controllers, don’t use POJOs to represent submitted form data. Instead, use a self-written form-parsing library that requires to create a member object for every request parameter. Make all these fields public and refer to them from JSPs, better several of them at once.
- Inherit these pseudo-controllers, so that you can’t tell what form fields are being handled without going all the way to the top of the class hierarchy.
- Include JSPs in other JSPs, and in the included ones, reference objects declared in the outer one.
- Create new sites by copy-pasting old ones, so that common functionality added along the way ends up being spread instead of consolidated in the core library. Ensure that every new UI-related feature requires modifying every site in which it’s already implemented.
- Hardcode application logic into JSPs, or into the obscurest classes you can find in random places.
- Tie the core library to the common admin panel, requiring it to be redeployed every time something changes.
- Make said admin panel ridden with editable features that don’t actually work because they weren’t implemented for this particular site but nevertheless can’t be disabled in the admin panel.
- For every feature, write two classes in different packages that do the same thing but slightly differently.
- Use lazy singletons everywhere. Inherit them and initialize them in the strangest of places so that everything breaks down if an include is forgotten.
- Use a self-written authentication system that randomly clears the session upon authentication for an unclear reason, and make the authentication so mind-boggling as to make that particular quirk as unfixable as possible.
- Make the admin panel (which every application depends on) cache the page tree for every single site that exists in the system upon loading, and write that part as inefficiently as possible, so that the server spends minutes reloading the application when it starts fetching page structures from the database.
- Have three different ways of sending mail and make each application use one that its developer liked the most.
- Upgrade the built-in proprietary JavaScript-based text editor with major pain, then downgrade it when it turns out that the customer bought the wrong version by accident.
- Make the menu handler return URLs that end in “.jsp” even though such JSPs don’t really exist and are all handled by one three-line JSP per page type.
- Require restarting the target server every time the utility copy application is used.
- Hardcode full URLs in the database, so that a text replace function has to be built into the utility application specifically to replace those.
- Make error messages that the end user sees as non-descriptive and user-unfriendly as possible. They’re sure going to be fascinated when trying to register an account to find out that “NAME_EXISTS”.
- Hire a web designer who insists on using table layouts, tag soup HTML, split images and no doctype on the grounds that everything should be compatible with IE5. In 2008.