The Decision about when to go Abstract and when to go Concrete exists in programming. Here are some random notes on the subject.
Deciding on the Level of Abstraction:
Too much concrete gets in the way of the abstract – abstract allow you to build code at a high level. Think of concrete as sludge. If you have too much of it you can barely move. Too much abstract buries the concrete – concrete allows you to maintain code. Think of abstract as water, too deep and you drown in it. The analogy of an effective system is wading through waist high water. The water(abstract) is fluid and flexible, the bottom of the lake (concrete) is muddy but supportive and can be walked on as long as the water is deep enough so that it supports most of your weight. Too little abstraction and you get stuck int he mud. Too much abstraction and you are over your head.
A common example of too concrete is using low level string manipulation rather than using regular expressions. In this case one regular expression can often replace dozens of lines of code. A common example of too abstract is ASP.MVC. It is difficult to trace where things are happening and step through.
Complete Abstract Systems
Go abstract if you can build a ‘complete’ abstract system. The challenge of complete abstraction is building a place to start debugging and maintaining code. A complete abstraction system has:
- storage (the magic strings appear nowhere except in the storage)
- admin (the magic strings are managed using an adequate admin system)
- magic strings do not appear in code, enumerations or case statements
- usage & middle tier & display
- benefit (a clear benefit is evident for going abstract)
- testing is adequate so that you do not have to dig down and debug much
- debugging display – bugs tell you how to fix them
- another clear benefit
- you can work with both data and information
- you can mix in concrete as necessary – including debugging ‘hints’.
- There is a place to start debugging, maintenance, and investigating the code in addition to the UI and database layers.
Not Going All The Way with Abstraction:
- if you see mounds and mounds of fairly similar code, your abstracting system is not complete.
- if programmers go crazy trying to figure out how you are doing things, then your admin/concrete hints system is not complete.
- if there is not ‘level above’, your system is not complete
Frameworks are an Abstracting System:
- The framework is good if it does not stop you from doing what you want.
- Concrete programming (without framework) is a concrete system.
- You can mix the two.
Abstraction can be used to:
- abstraction to ‘clean up the code’. This is often a good idea.
- abstraction to ‘genericize the forms’. This is sometimes a good idea.
- piling everything into one method or stored procedure, handled by parameters/queries. This is often not a good idea.
- table name stored in a variable. This is useful only in a ‘complete’ abstract system.
- case statements to set the value of table name variables. This is a bad idea.
- constructing dynamic queries in .NET. This is sometimes good, sometimes not.
- Using case statements where you could have just written two methods. This is a bad idea, let .NET do the work.
- using case statements to set a value where you could have just gotten a value out of a dictionary. This is a bad idea.
small abstractions are sometime quite useless, for example With/using.
Synching the Level of Abstraction:
Too many case statements may indicate over-abstraction combined with under-abstraction. The abstraction levels between things that need to work together have not been kept in synch. Things sometimes get out of synch when you are trying to do information things in code rather than data.
Debugging and Abstraction:
When you don’t abstract, you can go from the UI or the Database layer and figure things out. When you do abstract there is no obvious place to start.
The challenge of complete abstraction is building a place to start debugging and maintaining code.