We all know that software just writes itself. However, if you are willing to work really hard at it, you can still fuck it up.
Are you the person in charge of executing a large-scale software build? Then you need to know these 10 sure-fire ways to ruin a software project:
Always state what you need in as general terms as possible. If your team gives you specific requirements, always rewrite them into more general forms before giving them to developers. Developers love to hone their skills by rewriting the same components over and over again when you tell them it wasn’t what you wanted without first telling them what you wanted.
Ask For Quotes Before Giving Requirements.
If you have an internal team, you’ll want time estimates. If it’s an external team, you’ll want costs. Either way, insist on those after the briefest possible discussion (nothing in writing) of basic requirements. If they insist on something in writing, don’t write more than can comfortably fit on one side of a napkin. Then hold your developers to those estimates. This ensures that the team spends half their time just finding out what is needed, and the other half doing everything they can to squeeze the work into insufficient time. The result will be a wonderfully crap project with an excitingly low quality ceiling, and general depression and ill-will between all parties.
Always Make Changes After The Plans Are Locked In.
A professional team will make you pay for late changes, but that is ok. The main thing is to provide significant key changes after the solutions have been architected, thus ensuring that the delivered project will contain plenty of “tacked-on” elements, that it was never designed to incorporate.
Change The Direction of The Business During Development.
If you are building a product for a certain target market, try to change your market during development, and instruct developers to “keep this in mind”. For example, if you are building an online community for financial planners, change your market to target foreign students instead.
Never Explain “why”.
Don’t tell your developers why you need this project. Don’t tell them what it will do for its users, or for the business. Avoid sharing details about the reasons why certain features are needed. Thus your developers will be forced to stick to your own scantily-defined requirements as their sole source of knowledge about the purpose of what they are doing. This virtually ensures that you will get exactly what you asked for, rather than what is needed.
Always Hire Non-English-Speaking Teams.
All developers speak “code” right? By hiring foreign-language developers, you will also save a lot of money, which is really important, because you will need it to pay for the same project 4 or 5 times.
Set The Timetable On Business Objectives, Not Work Involved.
It is very important to be firm about your timetable. Always insist on having important milestones completed “for the presentation to Jim on the 25th”, rather than actually choosing dates based on the work involved. And try to do this once all the milestone timing has already been set. This is one of the best ways to ensure that each delivery is loaded with bugs, key features don’t work, and the things which do work were done early on, and have thus become unnecessary.
Only bad developers need Quality Assurance checking. If you have a skilled team (and a quick check of their foreign university transcripts can tell you that) then you should not worry about QA. Also, you should insist that if any QA is done at all, it should be done by having the developers check their own work. Don’t let them check each other’s work, as that can sometimes lead to accidental productivity.
Don’t Research Your Needs First.
One of the more subtle, yet highly effective ways to ensure project failure is to build the wrong solution. If you avoid basic preliminary research, you have a much better chance of crafting a solution that doesn’t take into account your market, your business case, your competitors, or the purpose of the solution. This way, even if a project turns out accidentally successful (it happens) it can still be rendered entirely useless.
Always Leave Things Unfinished.
You should never fully
If you diligently take these rules to heart, you are almost guaranteed to fuck up your software project. Happy building!
If you think of any other ways to sink a development project, let me know in the comments below.
Anyone who has ever managed any technical infrastructure will know how important it is to have a ready supply of cryptic and impressive-sounding reasons for why something didn't get done. But sometimes, you are just too busy Facebooking to think them up. So here is an automated, randomized excuse generator, that will give you a beautifully-crafted, technically impenetrable error message, perfect for those times when you need to get your boss off your back for just a few more hours so you can finish watching the rest of the season of the original lost Doctor Who episodes from 1964.
Just hit the button to produce another error message:
Okay, So you wanna geek your speak? Here are 20 (give or take) of the more obscure technical ways to insult someone. How obscure? Well, some you won’t even find on Google – which is just how we like it.
The lights are blinkenflashen but nobody’s home. This is usually applied to a person who has no clue, with no clue that they have no clue. Named after a server response code issued when you try to visit a webpage that simply isn’t there.
Assmosis in action. Used by geeks to describe those people in the office who are continuously sucking up to their superiors in order to absorb their success through “assmosis”.
Brute Force and Ignorance. A BFI operator is someone (usually in a corporate software development environment) who uses set policies and methodologies fanatically while studiously avoiding any rational thought.
A suit-wearing, cubicle inhabiting minion who is one of thousands of identical minions hired to write banking systems or payroll packages in RPG and other unspeakable horrors. See BFI operator.
Similar to a rubber-necker, who can’t help looking, a digi-necker will whip out a camera or phone to snap a video at any awkward moment, such as when grandma falls down the escalator and bursts her colostomy bag.
Drunk Mouse Syndrome. A condition afflicting some users, causing them to be unable to follow the simplest of instructions.
Someone who regularly googles their own name.
An amateur who knows nothing about photography, and just clicks at everything, then photoshops in some lens flare and calls it art.
Someone who refuses to acknowledge others’ privacy by insisting on sending out emails with dozens of addresses (including yours) in the “To” field, visible to everyone.
A code known to support services and helpdesks that describes a customer who is too dumb to use a computer. Often recorded in call logs and sometimes even on the user’s computer. For example:
“Mkay, just type that code at the top of your Win.INI file.”
“Will that fix the problem?”
“No, but it will help the next guy to understand what they’re dealing with, so you won’t have to go through that whole process again”.
A video gamer or who insists on using crap hardware, a poor connection, or both, thereby spoiling it for everyone else. They don’t usually last long: in the virtual world, they get fragged without remorse, in the real world, they are always first to get sent for pizza and cola.
Someone who will click on any link they are sent, often happily entering their banking passwords as well.
A particularly useless user.
The smooth-talking member of the marketing department who signs up users by promising that the next version of the product will have features which are unplanned, extremely difficult to implement, and/or in violation of the laws of physics. By next Thursday.
An individual so utterly loyal to a particular operating system or platform that they have achieved a state of religious zeal. Microserfs typically drool in response to a rigged demo.
A computer equivalent of a couch potato.
A person with no knowledge or awareness of anything remotely related to computers. The IT equivalent of Harry Potter’s “muggles.”
An ID-10-T user who simply cannot absorb what you are telling them. They cannot or will not listen. For example:
“So when you click on the ‘start’ button, what do you see?”
“The ‘start’ button, in the bottom left of your screen.”
“But it’s all just pictures!”
“Just click on the ‘start’ button.”
“The what button?”
A user who will agree to anything without reading it. Especially infuriating when you are trying to give technical support and they keep clicking “OK” on all the useful messages. See lemming clicker.
One of those bosses who is not good for much except when things go wrong, at which time they swoop in, make a lot of noise and crap all over everything.
Someone who maintains an online presence as a campaigner for causes, but is actually just another sallow, spotty youth who lives with their parents, and wouldn’t be caught dead at a protest rally.
An obnoxious individual engaged in the profession of marketing or management, who pretends to know “how it all works” – very annoying to those who actually do.
That student or co-worker who doesn’t really know the job, but pretends to by just slapping together everyone else’s contributions. For example (from “The IT Crowd”):
Mr Reynholm (the big boss): Jen, did I just see you googling “IT manager”?
Jen (the IT manager): Um…
It makes me want to find the best way of doing things. It makes me strive for greater productivity with less effort. It makes me think about each task before launching into it, so that I get the best possible efficiencies and outcomes. Being lazy is GOOD.
One of the biggest skills I’ve developed as a lazy programmer is the ability to automate. Many programmers and system administrators who are lazy (I believe the P.C. term is “efficient”) have a chronic aversion to repetitive tasks. This is a healthy impulse and should be encouraged. Many would happily spend 2 hours writing a script to automate a 15 minute daily process. If you were managing one of these people, you might be furious to find out how this time is being “wasted”. But stop and think for a moment. Leaving aside the fact that computers were invented in order to automate repetitive tasks in the first place, consider whether that time is really being wasted. For this daily 15 minute process let’s consider this timeline:
Day 1: 2 hours taken, productivity: -2:00
Day 2: 0 hours taken, productivity: -1.45 (15 minutes saved)
Day 3-8: 0 hours taken, productivity: 0
Day 9 onwards: 0 hours, productivity: +0:15
After a week and a half, we go into a positive productivity time balance. The script has effectively paid for itself. Each day after that, the script chugs away bringing in time savings. If you are one who counts the cost of every minute, consider that after a year that little script would have saved just over 91 hours. That is MORE THAN A MONTH’S WAGES for your programmer. Essentially, for the cost of 2 hours work, you’ve been able to get a whole month of extra work from your programmer. Its like having 13 productive months a year!
Now stop and think how many minor repetitive process make up an average day for your programmers or administrators. You can probably identify several hours per week that are taken up with repetitive tasks that could be automated. Let them loose on automating these tasks, or if they are not lazy enough, contract someone who is, to do the automation. In a short while, you will marvel at the increase in productivity and availability.
Meta-Aware… is that self-awareness? A self-aware system? Like Skynet, the evil take-over-the-world-and-kill-all-humans system, that dreamed up the terminators? No, not quite.
In this context, I’m talking about a system that is not explicitly programmed for every possible situation. Rather, it will look inside itself, in its own data, to see how a particular situation is to be handled… in terms of what it should expect, what processing it needs to do, where and how to return the output. The what-to-do-next instructions are not explicit, as is usually the case in programmed systems. The meta-aware system doesn’t “know” how it will react in a given situation until the situation arises.
I know what you are thinking: what’s the point? Or: is it even possible? Let me address these one by one:
What’s The Point?
The point is simply that you end up with a system of such flexibility, such adaptiveness and resilience, that a business can benefit mightily from using such a system as its core business engine. And yet, some of the most exciting benefits are felt during the development process itself. Let me highlight some of the major advantages:
True Delegation of Functionality: Different programmers (of varying prowess) can work on (and be responsible for) different areas of the system at the same time. This brings source control to a whole new level. Like Monty Python’s famous “funniest joke of all time”, you needn’t worry that any one person will see too much of the system at once (requiring hospitalisation). This also neatly solves the MVC problem. Not only does it keep the front-end (UI) in the hands of the front-end developers, but it also keeps the program code relating to front-end functionality (for example, PHP code to build an HTML list) in the appropriate hands also. And the same is true for the back-end, communications layer, database layer, business objects, and so on.
Preservation of Intellectual Property: The delegation of functionality above means that each developer only sees the parts they are working on, or at most, their library set. Yet the hierarchy of the system is known to all developers, and by design, each unit and library is fully documented. It has to be to form part of the meta-structure. All functionality is accessible, yet only permitted code is exposed. This preserves your intellectual capital investment from theft, but unlike other systems designed for this purpose, it manages to do this without reducing productivity or hampering developers’ creative flow.
Unparalleled Flexibility: This is not just an idle boast. The hallmark of any powerful system is that it can be made to grow beyond the uses that were envisioned when it was created. For example, cell phones were intended to be telephones. But by becoming computers, on which any given software can be loaded, the door is opened for them to be just about anything. So it is with a meta-aware system. If an unforeseen need arrives one day, you don’t need to put your whole team on it. Just add a new library (even that may not be necessary – a few definitions may do the trick) and suddenly your system is handling things that weren’t even conceived when it was designed. The same applies if a new protocol comes along, or if your suppliers or customers suddenly start insisting you use a totally new mechanism to communicate with their systems. No problem. A new (minor) library, or a few lines of service definition, and it is all done.
Transparency In Development: During development, the path to a meta-aware system is quite different from traditional development. The system will “grow,” almost organically, with each piece being completed as needed. Functional units may be delegated entirely to a team or an individual, and broken down further into classes, objects, procedures or functions. At any time, a quick glance will tell you exactly how each unit is coming along, and it is possible to view progress at the highest level (the entire project), or drill down to the smallest functional item. A well-built meta-aware system will be able to provide all this information itself, without recourse to external project or reporting tools.
Budget Enforcement: The core of a meta-aware system will not take long to build, and after that is done, you can settle back and proceed with adding branches, stems and leaves as the budget allows. This is great when development is funded out of cashflow, as there is always something for your developers to do, and they can be concentrated on areas of greatest need, but also moved to different areas of functionality when required. It is also very easy to spin up new teams or individuals quickly, and they can be spun down just as fast.
Potential To Reduce Time To Market: It is often said of software development that “Nine women cannot make a baby in one month.” And that is true, with traditional software development. However, because of the way a meta-aware system is structured, it becomes feasible to proceed on several vectors simultaneously. This comes into its own whether you are outsourcing all development or just overflow to cheaper communities, in India, Asia, etc., communication difficulties (which are often project-killers) tend to recede as functional units are broken down into basic building blocks. This also has the pleasant side effect of reducing the number of senior developers needed, as the actual execution will not require very strong big-picture skills.
Seamless Integration, Even With Legacy Systems: It’s great when you get to build a green-fields development, where you get to architect the system itself, as well as all other systems it may talk to to, including billing, communications, reporting, and so on. But this almost never happens in reality. Even in a green-fields project, it’s not advisable to re-invent the wheel, and an architecture that calls for the building of components that are already commercially available is probably not one you want to put your money into. In practice, even the most sequestered system is an integration exercise, talking to all kind of external systems. Usually those systems make up the product and service offerings that your business is depending on to provide to clients. They may be provided by you, or provided by a vendor, managed directly or managed in the cloud. A meta-aware system will have simple data collections describing those systems, with libraries to carry out each method of communication. Base methods can be developed (for example SSH session support) and then extended with platform-specific features (such as script calls in a SSH session). It makes no difference how diverse the systems are. All systems have inputs and outputs, and a meta-aware system will know just what to say.
Powerful Automation Capabilities: Wherever possible, you want to be able to turn a customer action into a result without any human intervention. For example, if an existing customer wants to upgrade or add a product, the events that flow from their action should result in the request being fulfilled (or denied politely, with an explanation), without human intervention. This is the magic key that unlocks a business’s ability to SCALE beyond what its staff can provide. In essence it gives you the ability to service customers while you sleep. A meta-aware system will know what services are available to each customer, and exactly what is needed to provision those services.
Integrate New Systems Without Code: Once a meta-aware system has had a few methods defined, integrating with a new system is simply a matter of storing a few definitions: namely, the types of actions available on a service, how to call those actions, what data to send, how to format it, and what to expect in return. Even if you are integrating with a system via a method that has never been defined before, you can simply extend an existing method. For example, a SOAP call is an extended subset of an HTTP call. With a well-built meta-aware system, integration becomes trivially easy.
This All Sounds Great, But Is It Even Possible?
Yes it is. I know because I’ve built one. It was a complete management system for an Internet Service Provider, covering the customer UI, the administrative UI, integration with (a broad range of) suppliers’ systems, telco integration, automatic provisioning, reporting, billing, business intelligence, and more. Several years on, I have no doubt that it is being used for a whole lot more than I could possibly have envisaged, and yet I know that each new capability needed only a few lines of code to make it happen.
So How Do I Build A Meta-Aware System?
It is surprisingly simple. Your core should look something like this:
I’ll explain the above by means of an example: an online, web-based email system (such as Gmail, Hotmail, etc). Let’s start with Services. A Service corresponds to the physical manifestation of an aspect of an entity. To express that mouthful in terms of our example, the service is a product, or product option, such as the mailbox itself, an anti-spam product, extra storage, and so on. Although our system controls this service, it is likely to be externally-hosted, with its own system and data. It may even be provided by a external vendor. The collection of Service meta-data is what tells the system what services are available, and how to manipulate them. The Actions collection will typically express what the entity is capable of doing with Services, for example, AddNew, CheckAvailable, ChangeExisting, DeleteExisting, and such. The Methods collection informs the system how to communicate with the external infrastructure that will provision, modify or delete the Service. For example, some services expect to talk via a SOAP or RESTful API, whereas some may be command-line-based. Some may return an “OK” response in plain text, whereas some may provide an ID that links to a response table. And finally, the Fields collection describe to the system what kind of data it should be sending when executing each Action, providing a translation between the fields of the internal entity data in our own datastore, and the fields that the Service expects to receive. It also defines any conversions that may be needed to make the data acceptable to the service.
How Does This All Fit Together?
Let’s consider an example sequence: a customer of our webmail system wants extra storage. The customer starts the process by visiting a web page (or application) that lists available services. If our meta-aware system thinks this customer is entitled to be offered the extra storage product, it will be displayed in the list of options. So our customer clicks on “Extra Storage” to start the ball rolling. In our system’s Fields collection, we are aware that certain information is needed in order to create an extra storage account. So we get some of the information from the customer’s record in our database, and some of the information (such as how much storage is needed) we get directly from the customer. Now armed with everything we need, the system sees (in its Methods collection) that the storage server should be spoken to using the SOAP protocol, with certain passwords for authentication, so it makes a SOAP call to the specified URL, calling the function to add a new storage account (which comes from the AddNew action in the Action collection). It knows what fields to send, and it knows what to expect in return. The result is analysed and the customer is informed of its success or failure.
That is the sequence through the core of our meta-aware system. In addition, you would also have an automation chain that ties into a billing system, product management system, and others. You may also have service groups, as it is quite likely that a real-world service is made up of several Services defined in our collection. For example, providing an email address means providing an alias, mailbox, POP3 access, IMAP access, and so on. Each one of these would be a part of an automation chain that links these services together.
In A Nutshell…
Now you know that a meta-aware system is equipped to decide what services it can offer, and to who, and it knows how to provision or manage those services, what to send, and what to expect in return. A meta-aware system can carry these actions through to conclusion without any human intervention. During its development, a meta-aware system can also simplify the development process, making it easier to achieve deadlines, share work, secure intellectual property, and bring teams up to speed. A meta-aware system can seamlessly communicate with any system out there, even cumbersome legacy systems, to do its bidding. A meta-aware system is the focal point of a mesh of disparate systems, all made to work in unison and controlled from a central point.