13

There are many answers in my previous question about simplicity relating to readability that helped me see my definition and understanding of simplicity in code was, quite possibly, incorrect.

How can I define simplicity in code? What software measurements and metrics are available to measure code simplicity?

4
  • 2
    @MarkTrapp There are other ways of discussing code simplicity without topics from empirical software engineering, topics that I'm far less familiar with. For example, discussing simplicity in terms of the ability to write automated tests. My skills and knowledge allow me to answer this question from the perspective of an emprical software engineer, while others can answer from alternative perspectives. Adding that statement to the question limits the number of useful answers significantly, making it (IMO) too localized. If you want to add it, you can, but this is a good question as it is.
    – Thomas Owens
    Commented Dec 6, 2011 at 15:34
  • 2
    @ThomasOwens Real questions have answers, not ideas or opinions. Narrowing down the scope so everyone interprets how to answer the question in the same way is exactly what Stack Exchange is about. There may be more than one approach to solving the problem, but there is only one unambiguously-stated problem.
    – user8
    Commented Dec 6, 2011 at 15:40
  • In its present state, there are very few answers to this question (my answer addresses the empirical software engineering standpoint, with the common metrics - there are probably others). It makes no sense to exclude answers providing valid alternatives from other perspectives, which is what the wording of this question does. I disagree fully with these edits and the question should be reverted to its original form.
    – Thomas Owens
    Commented Dec 6, 2011 at 16:02
  • @MarkTrapp The problem is unambiguous: How do I determine code simplicity? There are several good answers. Mine is use empirical software engineering techniques to measure complexity. Another might be to write automated tests and if it's difficult to write good tests, the code is complex - a perfectly valid answer. There might be others that I'm not aware of. If you need to measure complexity/simplicity of a code base, the question should be worded in a way to allow all of the alternatives to be presented so the asker can choose the best solution for his particular case.
    – Thomas Owens
    Commented Dec 6, 2011 at 16:05

3 Answers 3

16

The most common metrics for measuring the complexity (or simplicity, if you take simplicity to be the opposite of complexity) are McCabe's Cyclomatic Complexity and the Halstead Complexity Metrics.

Cyclomatic complexity measures the number of distinct paths through a given unit, usually a method or function, although it can also be computed on a class. As the number of paths increase, it becomes more difficult to remember the flow of data through a given module, which is related to the concept of working memory. High cyclomatic complexity tends to indicate difficulty in the ability to test a module - more test cases are required to cover the various paths through the system. There have also been studies that have linked high cyclomatic complexity to high defect rates. Typically, a cyclomatic complexity of 10 indicates that a unit should be reviewed and possibly refactored.

The Halstead complexity measures use the inputs of total and distinct operators and operands to compute the volume, difficulty, and effort of a piece of code. Difficulty, which is the (number of unique operators / 2) * (total number of operands / number of unique operands), is tied to the ability to read and understand the code for tasks such as learning the system or performing a code review. Again, you can count this on a system level, a class level, or a method/function level. There are a few postings about computing these measurements here and here.

Simply counting lines of code can also give you an idea of complexity. More lines of code means that there is more to read and understand in a module. I would be hesitant to use this as a stand-alone measurement. Instead, I'd use it with other measurements, such as number of defects in a given module to obtain defect density. A high defect density could indicate problems in writing tests and performing code reviews, which may or may not be caused by complex code.

Fan-in and fan-out are two other metrics, related to the flow of data. As defined here, fan in is the sum of the procedures called, parameters read, and global variables read and fan out is the sum of procedures that call a given procedure, parameters written to (exposed to outside users, passed in by reference), and global variables written to. Again, high fan-in and fan-out might be indicative of a module that might be difficult to understand.

In specific paradigms, there might be other measures or metrics that are also useful. For example, in the object-oriented world, monitoring coupling (desire low), cohesion (desire high), and depth of inheritance (desire low) can be used to assess how simple or complicated a system is.

Of course, it's important to realize that a lot of measures and metrics are simply indicators. You need to use your judgement to determine if it's necessary to refactor to increase simplicity or if it's not worth the effort to do so. You can make the measurements, compute the metrics, and learn about your code, but you don't want to design your system by the numbers. Ultimately, do what makes sense.

3
  • 5
    I know you mentioned it but its important to stress that cyclomatic complexity is really only useful at the function/method level and gets significantly more subjective/useless at higher levels.
    – Ryathal
    Commented Dec 6, 2011 at 16:30
  • The trouble is that while these measures are good a general guide. There are several cases where "bad" programs score well, for, example having a dozen functions, where a single function with two more parameters would suffice, and, conversely many "good" programs which are well written solutions to a complex problem can score badly. Commented Dec 7, 2011 at 5:52
  • @James I explicitly pointed that out. Any measurement or metric needs to be taken in context as an indicator that something should be looked at. It takes the judgement of an engineer to determine if corrective action is needed and what that action is. However, unless you are actively gathering data, there's no empirical way to know about potential problems.
    – Thomas Owens
    Commented Dec 7, 2011 at 10:56
7

Instead of looking at a formal mode of defining simplicity, i would rather like to define simplicity as an attribute of quality of code writing.

I am not putting some measure of simplicity but when do you call something simple or not.

1. Code Traversal:
How easy it is to navigate through the code? Is it easy to spot where the API functions are written? Is it easy to understand call flows, for example which methods are calling others (and why)- are there good state machines implemented or cleanly identified algorithms?

When the code traversal is easy, the code is simple to follow.

2. Naming
While other codding standards help make code look cleaner - the most important thing is the naming of classes/object-instances/Variables/methods. The use clear and unambiguous names is clearly has a great impact on the Simplicity of the code. When it is difficult to identify a simple name, it is a sign that you might want to re-think the idea being that variable/method.

3. Interpretation and references
Does each of your method has a clear role to play. Does each variables/attributes are easy to determine the role they are playing? When a piece of code does something which has implies assumptions or affects unrelated set of variables, can become a maintenance nightmare.

4. Dependency or coupling
This is difficult to judge just by looking at the code, but becomes very evident if someone tries to fix your bugs. When some other things change in some other object, does the operation here changes? Are those changes obvious? Do you require to change the API so often to accommodate stuff. These suggest that intermodule relationships is not simple

5. Inputs User or Applications
Finally how simple are the user inputs or application are accepted on the API/UI? When multiple possible Users/Applications (for different purposes) needs to give you - are they obvious? Are there states/details that are not related to the higher abstraction but still goes back-n-forth the interface?

A simple question i would generally ask is as follow: If instead of a program, if i would have asked the same function to be performed by a human, would i have filled this information on a paper form? If not, i am not simple enough here.

I won't say this list is exhaustive, but i but i guess criteria is how easy or difficult it is to use and modify the software. That is simple.

9
  • 1
    He asked for measurements and metrics. These are subjective, so I don't think they are very on point.
    – psr
    Commented Dec 6, 2011 at 19:05
  • @psr I agree with you. It was also very evident from the answer from the answer of Thomas. However, he mentioned simplicity relating to readability. The Answer of Thomas deals with Cyclomatic complexity - this tells you how complex it is to test the code and not how complex the code is in terms of readability and may to extend maintainability. These are two very different concepts. Which is precisely why i wrote this answer to put the stark contradiction. Unfortunately to my knowledge there are no metrics which refers to simplicity of code in terms of readability. Commented Dec 6, 2011 at 19:10
  • "use names which are impossible to get misunderstood" - IMHO this is aiming way too high, to an irrealistic and impossible goal. I would rather not try to be so definite and simply say "use clear and unambiguous names". Commented Dec 6, 2011 at 21:32
  • @PéterTörök I agree. I think usually, in many organizations, very clearly defined rules of naming conventions and still some confusion about the intension of the particular variable persists. So emphasis was to say that clarity of purpose amounts to simplicity as opposed to a formal rule. May be i went overboard in how i described. Thanks. Commented Dec 7, 2011 at 5:07
  • @Dipan Cyclomatic complexity is related to the readability of the code, through working memory. Code with high cyclomatic complexity (or even just high block depth) is difficult to keep in working memory, therefore more difficult to read straight through.
    – Thomas Owens
    Commented Dec 7, 2011 at 10:57
0

I am not aware of any good existing metrics for code simplicity (it doesn't mean they don't exist - just that I don't know about them). I could propose some, maybe some will help:

  • Simplicity of language features used: if the language has features that might be considered "advanced" and "simple" you could count the number of occurrences of the advanced features. How you define "advanced" might be a little more subjective. I supposes some might say this is also like measuring the "cleverness" of a program. A common example: some might say that the ?: operator should be an "advanced" feature, others might disagree. I don't know how easy it would be to write a tool that can test for this.

  • Simplicity of constructs within the program: You could measure the number of paramters a function will accept. If you have > n % of all functions with > m parameters, you could choose to count it as not simple, depending on how you define n and m (maybe n=3 and m=6?). I think there are some static analysis tools that can measure this - I think JTest simply measured functions with > m parameters.

  • You could try to count the number of nested loops or control structures. This I think is actually not a bad metric and I think there's a name for it (can't recall off the top of my head). Again, I think there are tools (again, like JTest) that can measure this, to a degree.

  • You could try to measure "refactorability". If your code contains lots of pieces of code that could be refactored but aren't, maybe that would could as not simple. I also recall from the time I worked with JTest that it tried to measure this too, but I remember I didn't often agree with it in this case, so YMMV.

  • You could try to measure the number of layers between different parts of your system. For example: how many different pieces of code will touch data that comes from a web form before it gets stored in the database? This could be a tricky one to measure properly...

5
  • 2
    I believe #3 is called block depth. It's also related to Cyclomatic Complexity if there are decisional control structures involved.
    – Thomas Owens
    Commented Dec 6, 2011 at 16:11
  • No downvote explanation? Commented Dec 6, 2011 at 17:12
  • Can't agree with "simplicity of language features". Advanced features are there to simplify the code. Using only the simple, basic features will obscure what the code is actually doing, it unavoidably leads to leaking abstraction layers. Advanced language features allows to express higher levels of abstraction, leaving your code much more dense and readable. The more advanced features you're using (wisely, of course), the better for simplicity. Just compare a code in, say, Matlab (which is "advanced" indeed) with a similar Fortran code made of basic features only.
    – SK-logic
    Commented Dec 7, 2011 at 10:01
  • And I won't agree with a number of layers metric as well. If you can do something in a dozen of trivial and clean steps or in a one twisted transform, better do it in a number of steps. Many simple and clearly separated layers is much better (and simpler) than a single twisted layer.
    – SK-logic
    Commented Dec 7, 2011 at 10:05
  • @SK-logic: I guess I should have called that one "cleverness", it's closer to what I meant. I'd only say that things like ?: are a problem when they're nested 5 deep. As for layers, cleanly separated layers are better than one convoluted layer. But 7 mostly-redundant layers, when only 2 or 3 were necessary is a bad thing. Commented Dec 7, 2011 at 15:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.