Complexity within Software Engineering

Since the most fundamental program ever written it seems some architects and software developers feel the need to demonstrate, what they believe, is their superior software engineering skills by designing to an additional unspecified requirement. The unspecified requirement in question is complexity.

Complexity is not a design pattern to further ones career and I would argue that complexity is, in actuality, an anti-pattern in furthering ones career. As software engineers we should strive for simplicity and although it may not always be possible, we should ask ourselves if the level of complexity within the software we write is at an appropriate level and determine if refactoring the software could reduce the level of complexity. 

Software should be written to be as simple as possible while still achieving the requirements for which the software is intended. It is especially true even if you consider yourself to be a guru developer in the particular language, technology, or platform to be used. This is because not everyone on the team, or everyone who will ever work on the team, will have the same skill level with that given language, technology, or platform.

If a system is written using the .NET framework, for example, the system should use the data access capabilities of ADO.NET or the presentation capabilities of ASP.NET. If someone was to write their own data access or presentation capabilities it will merely reduce the maintainability of that software. It would then be very doubtful that any business requirements existed that would necessitate such a deviation from those standard framework API’s.

Are their occasions when writing your own version of an existing capability can be justified?

Yes there are, although you should always be able to provide justification in terms of business objectives for such a deviation from the standard capabilities provided within frameworks such as .NET or J2SE. Associated software development methodologies should also enforce the use of standard frameworks and provide a process by which appeals can be made to the architects and managers of a system on those occasions when a deviation is necessary to meet a business requirement. It is more likely, however, that the business requirement could be met by extending the existing framework capability rather than requiring an entirely new capability to be designed and written from scratch.

Wherever possible software should be written such that another developer, familiar only with the base technology (e.g. Microsoft .NET or J2SE etc.), would be able to rapidly become as effective as you if they were to join the team. Ideally this should be true without substantial assistance from those originally on the development team, and as such it is necessary to provide adequate documentation and code commenting when writing software based systems. Complexity therefore must be regarded as an anti-pattern and should be refactored out of software wherever possible.

I originally posted this on the Intel Software Network and you can see some of the comments to that post here.

Comments (2)

  1. Robert Zych says:

    Hi Doug,

    Thanks for republishing this interesting article on your new blog. I completely agree with you on this topic of complexity, and I particularly enjoyed your last sentence, “Complexity therefore must be regarded as an anti-pattern and should be refactored out of software wherever possible.” I strongly believe that accidental complexity is a growing problem in our industry, and that we as responsible software craftsmen must take action to confront these types of issues if we want the practice of software development to evolve into an established profession. Having said that, I’m not entirely sure that software development should be regarded as purely an engineering discipline because there are many issues within software that are subjective. For example, if I compose a software component from the latest .NET technologies (i.e. LINQ, F#, C# 4, Rx, etc…), then in theory that component should be less complex and more powerful than the same component built using legacy technologies. However, if the entire development team is not versed in those chosen technologies, I would have introduced an un-maintainable component which might even reduce the overall stability of the system. In this context, how would you apply these new best practices?



  2. Doug Holland says:

    Hey Robert,

    When introducing a new technology to a team there should always be some thought given to how the given technology will benefit the project and how well the team is equipped to leverage that technology.

    If the new technology is merely some additional types then the team should be able to learn, and effectively apply these new types, very quickly. Obviously code should be written with another developer in mind, the developer reading the code months after it is written, such that he or she can understand the intent of the original developer.

    When the new technology requires some shift in thinking, such as with functional programming, it may be necessary to have the team study the technology before it is adopted within the organization.

    As architects and developers we should resist the urge to adopt a given language or technology, simply because it is regarded as cool upon the blogosphere. That said however, we must continuously take time and energy to learn those new languages and technologies that make sense for the environments within which we work.


    – Doug