RSS
 

Archive for the ‘Fundamentals’ Category

Socrates on SOLID: The Dependency Inversion Principle

15 Aug

This is the sixth and final in a series of (hopefully) amusing posts into Robert Martin’s SOLID principles.  It’s written as a dialog between Socrates and a student named Loej in the spirit of the dialectic method popularized by Plato.  In this post, the principle explored is the “Dependency Inversion Principle”.  I hope you find this enjoyable.

Socrates, who is the narrator of the dialogue.
Loej, who is but novice at the master’s feet.

Socrates: Here we are then.  Do you recall what we discussed last time?

Loej: Yes the interface segregation principle.

Socrates: And what did this principle encourage?

Loej: It encourages dividing up interfaces so that, in general, each client gets its own interface.

Socrates: Very good.  Today we discuss the last of Robert Martin’s SOLID principle, the Dependency Inversion principle.

Loej:  I think he must be quite avuncular for giving us all this insight.

Socrates: Indeed.  Anyway, the dependency inversion principle is perhaps the most counterintuitive of all of the SOLID principles.

Loej:  Yeah it sounds like standing on your head while coding.

Socrates:  Making the comprehension curve steeper is that this principle has taken on a life of its own.  It has become a focal point for advocates of dependency injection and inversion of control containers.  But these are not fundamental to the idea of dependency inversion.

Loej:  So what is dependency inversion?

Socrates:  According to Robert Martin, dependency inversion is a two part concept.  First, high level modules should not depend upon low level modules.  Rather, both should depend upon abstractions.  Second, abstractions should not depend on details.  Details should depend upon abstractions.

Loej:  Wait please. One brain overload at a time.  What is a high level module?

Socrates: Well, at the time Robert Martin’s original SOLID articles were written, a software movement called Structured Analysis and Design was becoming entrenched in software development.

Loej: You do realize that abbreviates to SAD.

Socrates: Indeed, and it was a bit sad.  At that time we lost site of the code.

Loej: How so?

Socrates: Senior software staff were encouraged to stop coding and start architecting.  Their job consisted of diagramming software processes at a high level and then exploding them into lower levels.  In SAD, high level modules were defined by lower level modules ad nauseam.  Abstractions were cut into pieces until defined by the gritty details.

Loej: Isn’t that what we have been taught by schools and almost all books?   Haven’t we all been taught to think of software as smushing small bits into classes to create abstractions?

Socrates: Yes and we need to understand programming at that level, the concrete implementation level.  But many of us stop when we can create an abstracted program from concrete parts.  This is a natural stopping point, because this is the first time the code “works”.

Loej:  But if it works, it works, right?

Socrates: What you really mean is that it works right now.  Are you familiar with Ward Cunningham’s concept of technical debt?

Loej:  You mean the second mortgage I took on my house to buy an MSDN Ultimate subscription?

Socrates: It’s the future pain we accrue with interest for doing things quick and dirty now.  Have you ever cut corners for speed when a deadline was looming?

Loej:  Sure.  I think we all have.

Socrates: What usually happens?

Loej:  We wind up having more defects or more trouble making changes down the rode.

Socrates:  That’s technical debt, and unfortunately sometimes our frameworks encourage it.   The last time you had to change your code to accommodate a new framework technology, what was it like?

Loej:  It was like pulling weeds throughout the entire codebase.

Socrates:  What if instead of composing classes from framework bits you composed them from abstractions?

Loej:  Sure, but at some point you have to tie into the specifics.

Socrates:  But you choose how and where you tie into the specifics.  Can you strive to avoid having abstractions take unreasonable dependencies?

Loej:  Sometimes the framework or specific technology dictates it though.

Socrates:  True enough.  Martin Fowler presented the idea of code smells when looking at target code for refactoring.  I propose a similar idea when considering using a new .NET framework technology – a framework taste.

 Loej:  You’ve got to be kidding.

Socrates:  I’m not.  Do you like diet soda?

Loej:  Sure.  It was an acquired taste though.

Socrates:  Diet soda tastes good after the first sip but leaves a bad aftertaste.  You can get used to that though if you stick at it.

Loej:  What does this have to to with .NET?

Socrates:  Many .NET framework technologies are like that diet soda.  They demo well but you know fundamentally it’s pretty nasty stuff.  Still, if you stick with it, no matter how bad it is, you learn to love it.

Loej:  That’s kind of funny.

Socrates:  Now how about a fine Scotch?  What did it taste like when you were a kid?

Loej:  Horrible.  Like a shag carpet

Socrates:  Exactly. It was too complex a flavor.  You had to grow into the nuances.  Unlike the soda, you didn’t lean to tolerate it, you learned to appreciate it with maturity.  Good framework technologies are like that.

Loej:  I think we’ve totally lost site of dependency inversion.

Socrates:  What I am getting at is that some technologies encourage SOLID principles and minimize technical debt.  They help you fall into the “pit of success”  Others heap on the technical debt with each new line of code.  In regards to the dependency inversion principle, look for technology and patterns that helps you minimize dependencies and help you build self defining abstractions.

Loej: Well this has all certainly been insightful.  Thank you master!

Socrates: Indeed.  I hope you have found the SOLID principles a good starting point for thinking about software design.  For more information check out the Los Techies, Code Better or the place it all started at, Object mentor.  Until next time, remember to keep your code SOLID!

 
 

Socrates on SOLID: The Interface Segregation Principle

23 Dec

This is the fifth in a series of (hopefully) amusing posts into Robert Martin’s SOLID principles.  It’s written as a dialog between Socrates and a student named Loej in the spirit of the dialectic method popularized by Plato.  In this post, the principle explored is the “The Interface Segregation Principle”.  I hope you find this enjoyable.

Socrates, who is the narrator of the dialogue.
Loej, who is but a blink of data in the maelstrom of the Net.

Socrates: We have we made great progress in our understanding of the SOLID principles. So far we have discussed the Single Responsibility Principle, the Open/Closed Principle and the Liskov Substitution Principle. Do you recall what each of these mean?

Loej: Yes. The Single Responsibility Principle says that a software entity should have only a single responsibility. Robert Martin further clarified this to mean that a class should have only one reason to change.

Socrates: Nicely stated. And the Open/Closed principle?

Loej: Easy enough. Software entities should be open to extension and closed for modification.

Socrates: And the Liskov substitution principle?

Loej: The Liskov substitution principle…

Socrates: Yes?

Loej: It said something about sets and subsets.

Socrates; Right. But what did we infer from it?

Loej: Oh. A consumer of a base class should remain ignorant of its subclasses.

Socrates: Great. Did we get a bit more from it?

Loej: Right. It says that descendants shouldn’t dictate the behavior of their parents.

Socrates: And also?

Loej: A descendant should guarantee the behavior of its parents or it shouldn’t inherit from it.

Socrates: Precisely! Another way to state the entire thing is that the the preconditions of a derived class routine must be the same or weaker to the base class and the post conditions of a derived class routine must be the same or stronger than the base class.

Loej: Uh.. I’ll take your word on that one.

Socrates:Today we discuss the I in solid, the Interface Segregation principle.

Loej: Ok. What does that mean?

Socrates: The interface segregation principle says that clients should not be forced to depend upon interfaces that they do not use.

Loej: Well that seems straightforward enough to enforce.

Socrates: Well it is now and it’s so fundamental in .NET today thanks to Interfaces it is often an afterthought. But originally Robert Martin had to use multiple inheritance to support it.

Loej: How is that? I heard multiple inheritance is bad.

Socrates: C++ doesn’t have interfaces as a language feature, so if you want to support more than one abstract interface without mucking up your inheritance hierarchy, you need to use it.

Loej: And in Java and C# we use interfaces?

Socrates: Exactly. If we follow the advice to the letter, almost every client should have its own custom interface.

Loej: Well, the benefits seem obvious.

Socrates: There’s another benefit Robert Martin didn’t discuss. Let me ask you, how many things can you keep in your head at once?

Loej: 7 +/- 2. I’ve heard that statistic a number of places.

Socrates: What if I told you you could remember much more than 7 +/- 2?

Loej: How so?

Socrates: By a process cognitive scientists call “chunking”. Try to remember these letters. A, M, T, I, F, A, N, S, L, H, P, C…

Loej: I’m already lost. I told you, I can only do about seven letters.

Socrates: But what about these letters? AAPL, MSFT, INTC

Loej: Oh I recognize those. Those are the stock symbols for Apple, Microsoft, and Intel.

Socrates: Did you know the second group had the same exact letters as the first group?

Loej: Really?

Socrates: Indeed. But you remembered the second group much easier. Why is that?

Loej: Because they were put together into meaningful stock symbols. I recognize those.

Socrates: And the first?

Loej: A tangled mess of letters. But what does this have to do with this principle?

Socrates: When interfaces are more targeted, they chunk more naturally. Similar to how the Single responsibility principle focuses each software entity to a specific purpose, so the interface segregation principle focuses each interface to a specific purpose, typically one per client.

Loej: I see. Like grouping the letters into stock symbols. I can see the benefit . It’s much easier to deal with small simple things than large things.

Socrates: Yes. But for the record, of all the SOLID principles, I am most dubious of this one.

Loej: Didn’t you just spend the last five minutes convincing me of this principle? What gives?

Socrates: I believe this principle is slightly misguided. To split up large interfaces into small ones always will achieve looser coupling, but high cohesion is a different matter. There is no guarantee of high cohesion.  For example. Are these groups of letters easier to grasp than the random letters? AMTI FANS LHPC.

Loej: Not really, no.

Socrates: And yet they have been segregated into groups of the same size – 4 each.

Loej: But if you are really dividing up an interface based on client needs it wouldn’t be so arbitrary.

Socrates: True, this is contrived. But why should client dependencies dictate your design any more than other aspects?

Loej: What do you mean?

Socrates: In a domain driven design, quality interfaces are a natural aspect of the system. To segregate interfaces by client technology without the domain driving the process seems unnecessarily technical.

Loej: I see.

Socrates: One more to go Loej! until next time!

 
 

Socrates on Solid: The Liskov Substitution Principle

22 Dec

This is the fourth in a series of (hopefully) amusing posts into Robert Martin’s SOLID principles.  It’s written as a dialog between Socrates and a student named Loej in the spirit of the dialectic method popularized by Plato.  In this post, the principle explored is the “Liskov Substitution Principle”.  I hope you find this enjoyable.

Socrates, who is the narrator of the dialogue.
Loej, who is but a tiny minnow in a sea of 1′s and 0′s

Socrates:  Welcome back Loej.  Last time we discussed the Open / Closed principle.

Loej:  Yes.  We agreed that software entities should be open for extension but closed for modification.  In .NET, careful use of Interfaces help us achieve this goal.

Socrates: Excellent. Today we will discuss the ‘L’ in Solid, the Liskov substitution principle.

Loej: Gazoontite.

Socrates: Huh?

Loej:  Oh, I thought you sneezed.

Socrates: The Liskov substitution principle states that, if for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.

Loej:  Got it.

Socrates: Really?

Loej: Yes.  It makes perfect sense.  Crystal clear.  I think we’re done.

Socrates:  Well what does it mean then?

Loej:  It means that if for each o1 (mumble) such that (mumble mumble) the behavior of (mumble) and Q.E.D. Can I go now?

Socrates: But you just repeated what I said, more or less.   Look this one is fairly straightforward.

Loej: Alright then. Let’s get on with it.

Socrates: According to Liskov if in all cases I can substitute type A for type B then A is a subset of B.   So If I could substitute Circles, Rectangles, and Squares for…

Loej:  Shapes?

Socrates:  Or snakes, sharks, and monkeys for…

Loej:  Politicians?

Socrates:   I was thinking animals.  But if I can substitute one for the other,  then I have a subtype to type relationship.

Loej:  But this is just basic tenant of object oriented programming.  A Cat IS AN animal.  A Circle IS A shape.

Socrates:  So then anywhere I expect an animal, I should be able to pass a cat, or a brontosaurus, or any other animal?

Loej:  Yes.  A brontosaurus IS A dinosaur which IS AN animal.  You can pass them to a function that takes animals without a problem. That’s a basic property of polymorphism.  I don’t see anything terribly profound here.

Socrates:  Well, there is an important corollary which can be derived from the Liskov principle.  Anywhere code expects a base type, the program shouldn’t need to know it’s getting a derived type.

Loej:  So if our function takes an Animal it shouldn’t need to know that it’s really getting a Cat?  But why not?

Socrates: What would happen if we added a Dog type?

Loej: I see.  We might find that we had to modify the function that took an Animal to update its behavior for the Cat type in case it overlaps with the Dog type.

Socrates: Right and this violates the Open/Closed principle.  But there is one more serious problem.  If our function takes an Animal and then interrogates its subtype to discover how to handle the animal, the base type has taken a dependency on its subtype!

Loej: That would be bad.

Socrates:  There’s an even more subtle side to the Liskov substitution principle.

Loej: What’s that?

Socrates: Just as it would be incorrect for a subtype to dictate its parent’s behavior, it is incorrect to assign a subtype that cannot guarantee its parent behavior.

Loej: But that’s not possible with an IS A relationship, right?

Socrates: Actually Bob Martin’s paper on the Liskov substitution principle discusses this in depth.  IS A doesn’t guarantee behavior of subtypes conform to base types.  To really get inheritance right takes some deeper thought.

Loej: If I can’t depend on IS A what can I depend on?!?

Socrates: Well, usually IS A ‘IS A’ valid criterion. Most of the time two classes in an IS A relationship will have the same behavior as you move down the inheritance tree.  But think before your inheriting.  Make sure that behavior and constraints are enforceable down the tree.

Loej: Well I definitely have some thinking to do.

Socrates:  Until next time my friend.

 
 

Socrates on SOLID: The Open/Closed Principle

25 Nov

This is the third in a series of (hopefully) amusing posts into Robert Martin’s SOLID principles.  It’s written as a dialog between Socrates and a student named Loej in the spirit of the dialectic method popularized by Plato.  In this post, the principle explored is the “Open / Closed Principle”.  I hope you find this enjoyable.

Socrates, who is the narrator of the dialogue.
Loej, who is but a bit of sand in the maelstrom of software development.

Socrates:  Welcome again Loej.  Last time we discussed the Single Responsibility principle.

Loej:  Yes.  We agreed that, in general, each class should have one responsibility; each class should have only one reason to change.

Socrates: Excellent. My question today is this.  Have you ever experienced technological 20/20 hindsight?

Loej:  You mean regret a technical decision?  Of course.  I think all software developers have.

Socrates:   I’m talking more about clarity, not regret.  Have you ever had a better understanding of the domain or a customer’s needs as you progress through development.

Loej:  That usually happens as we go along during our iterations.

Socrates:  What about after deployment?

Loej:  That happens to.  Often times once a product is in the wild we gain a lot of insight and get a lot of feedback from customers. If we can, we try and refactor the code to incorporate feedback.

Socrates:  Let’s clarify something.  You can’t refactor code to incorporate change. Refactoring is a transformation of code that improves software design but does not change software behavior.

Loej:  Oh.

Socrates: Anyway, So what you are saying is to use your newfound clarity, you rewrite the code to change its behavior.  That’s fine during a fluid design of new code, but what about existing code that has stabilized, like after you have deployed?

Loej:  Well, it’s usually no biggie. You just need to look over the whole project and make sure you don’t break anything when you rewrite.

Socrates: How are you sure you didn’t break anything?

Loej: You have to check all of the dependent classes.

Socrates: Check?  You mean test?

Loej: Right. Check, test, just make sure it still works right.  And you may have to do some rewrite some tests too.

Socrates: But doesn’t this risk breaking your existing functionality?

Loej: Well, you can’t change existing behavior in a class without rewriting its code.

Socrates: That is true, but you reisk breaking something.

Loej: Then what are you supposed to do?  You said we are changing the behavior of the program.

Socrates: Well, if you can’t change existing code in an existing class?

Loej:  I get it.  You want me to say create a new class.  But then you’ve got all these dependencies pointing to the old class. You will have to recode those dependencies to point to the new class.  You are still rewriting lots of existing code.

Socrates:  What a conundrum.  I propose instead of scurrying to cover new functionality here and there you incorporate the Open/Closed principle into your design.

Loej: Ok I’ll bite. Just what is the Open/Closed principle?

Socrates: The Open/Closed principle states that Software Entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.  A modern interpretation would say that a class’s public facing interface should never change.

Loej: That sounds like Poppycock.  Every time you want to make a small change you would have to create a new class.  That’s a whole lot of work.

Socrates:  Ah, but we lucky .NET programmers have the luxury of interfaces.

Loej: How does that help?

Socrates: By using interfaces the parts that shouldn’t change don’t need to  We solidify the public facing parts in interfaces and agree to only use those interfaces.

Loej:  Ok, let me think about this.  You’re saying if I need to change behavior I create a new class and implement the existing interface?

Socrates: Yes.

Loej:  And if I need to add functionality to an interface?

Socrates: You don’t change the interface.  You create a new interface, possibly deriving from the old one.

Loej: I’m not convinced. You still have to change that code somewhere – the bit that bind classes to interfaces.  I mean somewhere you have to wire everything together and new up the instances.

Socrates: You’re right.  There is a problem of tying everything together, and that opens up a whole new discussion about abstract factories and dependency injection.

Loej:  Ok, I can put that aside for a second. But you still haven’t convinced me.  I see a maintenance nightmare.  I see ICustomer1, ICustomer2, ICustomer3…

Socrates: Which brings us back to the single responsibility principle we discussed yesterday.  If each class truly has a single responsibility, a single reason to change, that won’t happen.

Loej:  Hmm.  I’ll have to ponder it.

Socrates:  I see this as a technical debt mitigation technique. During initial development interfaces are rightfully in flux and should be more fluid.  As things stabilize though, this principle becomes important.   Still, it doesn’t take much additional effort to correctly apply this principle.

Loej: Well, interesting as always.

Socrates: Indeed.  Until next time.

 
 

Socrates On SOLID: The Single Responsibility Principle

24 Nov

This is the second in a series of (hopefully) amusing posts into Robert Martin’s SOLID principles.  It’s written as a dialog between Socrates and a student named Loej in the spirit of the dialectic method popularized by Plato.  In this post, the principle explored is the “Single Responsibility Principle”.  I hope you find this enjoyable.

Socrates:  Welcome again Loej.  Last time we agreed that software development is, as Steve McConnell puts it, a wicked problem.

Loej:  Right.  We have to solve software problems again and again to get them right.  This means change is an inherent part of the software development process.

Socrates:  And we agree that when we write code, we must anticipate change in order to manage complexity.

Loej:  Right and managing complexity is the fundamental concern of software engineering.

Socrates:  Very good.  When we talked before you said that in your experience, even a simple change can be difficult to make and may cascade into unrelated changes.

Loej:  Right. I remember when our company went international we had to add a shipping country for just about everything.  Products, customers, you name it.  I mean dragging the new fields to our forms was easy enough.  Master are you OK?

Socrates:  (Shivers) Continue…

Loej: But then we had to change the database code in the Customer form, the Product form, and the Supplier form. And we had to change our validation controls on all the forms.

Socrates: And?

Loej:  We introduced a defect. But at first we thought it was a bug with our printing object.

Socrates:  Your printing object?  How’s that?

Loej: We had an object which printed everything out.  It did things like PrintW2, PrintCustomerInvoice, PrintAddressLabel, stuff like that.  All of a sudden invoices and address labels stopped printing!

Socrates:  Did you track it down?

Loej: Yes after a few long days.  It turned out that we were writing a null to the customer table and when we retrieved the customer from the database in the Printer object, we got back a null as well.  This null was being appended to the address string and this caused the printer to not print!

Socrates:  Ouch.

Loej: Yeah bad memory.

Socrates:  No pun intended?

Loej:  Hmm?  Oh, no.

Socrates: I see.  Let’s start at the beginning.

Loej:  Sounds good.

Socrates:  You had one user directed change, to internationalize shipping, but this change required you to change some really big classes.

Loej:  Right.

Socrates: And in doing so you introduced a defect.

Loej:  Right again.

Socrates:  And the defect was originally thought to be in the Printer object, which was also a large class which did all things printer related.

Loej:  Yes.

Socrates:  If the printer class had been simpler, would it have been easier to debug?  Easier to test?

Loej: Well, that code would just need to be somewhere else.

Socrates: Right, but would you have had to look so hard to find the defect?

Loej:  You mean if we had a class whose job was to just print customer invoices? And a class just to print address labels?

Socrates:  Exactly.

Loej:  But wouldn’t this violate the don’t repeat yourself principle, you know, DRY?  I mean wouldn’t we need a bunch of code repeated in each of those little classes?  And doesn’t a bunch of little classes add complexity which we were trying to mitigate in the first place?

Socrates: Good questions. Let me address your first concern, DRY.  Why do you think it would be violated?

Loej: Well, we had methods in the printer object that formatted strings and checked that columns were correct and all that stuff.  All of these things relied on shared methods in the printer object.  We’d have to duplicate that in every new object.

Socrates:  Would you really?

Loej:  Oh, you’re suggesting we could keep those things in the printer class?

Socrates:  Or a couple new classes.

Loej:  Ok I get it.

Socrates:  Right.  So let’s not worry about DRY.  Now about your second concern, bunches of little classes.

Loej:  Right, we would have like 20 classes instead of one.

Socrates: And this adds complexity?

Loej:  Totally. I mean who can keep track of 20 things in their head.

Socrates:  Would you rather keep track of 20 classes or 20 methods of one class?  Isn’t this really the same thing?

Loej:  Well, there are a lot more files around.

Socrates: Could you use folders to simplify that?  And don’t multiple small files work better with your revision control system anyway?  And don’t modern IDEs take care of this?

Loej:  Points taken.  But automatic completion would become a mess…

Socrates:  What about using namespaces to handle that?

Loej: Ok.  So there’s not much difference in terms of complexity between twenty methods and twenty classes in modern software development with modern IDEs.

Socrates:  And actually using namespaces and folders you can simplify things more with separate classes than you can a single monolithic object.  Let’s move on then.  We agreed earlier it’s easier to find defects if they are more focused.

Loej:  Right.

Socrates: Would it be easier to not inadvertently introduce defects if objects were smaller and more focused?

Loej:  I suppose so.

Socrates: So would it make sense to divide up your validation logic, display logic, data logic, and business logic into separate classes?

Loej:  Well it would have made it possible to do some testing.

Socrates: Taking this idea further, what if each class had a single responsibility.  If each class just did one thing?

Loej:  That would make it easier to test.  But how do I know when I’m done dividing things up?  How do I know when I’ve got the right level of granularity? I mean, our printer object only handled printing.  And our forms only did one thing.  Like the supplier form handled suppliers. I mean at some level of abstraction, everything only does one thing.

Socrates: Well what do you mean when you say the printer object only handled printing?

Loej:  In the case of the printer object it meant that it only handled printing.  It printed invoices and it…

Socrates: Hold up!

Loej: What?

Socrates:  You said the word "and".  I think that’s a good sign you are breaking this rule when describing a class.

Loej: You mean that if I use the word "and", I have more than one responsibility?

Socrates:  Exactly.

Loej:  Ok I’ll buy that.  But how do I know if I have the right responsibility?

Socrates:  That’s going to depend on your domain model and a second rule of thumb.

Loej: What’s that rule?

Socrates: According to Robert Martin who formulated these SOLID principles, each class should have one and only one reason to change.

Loej: That sounds arbitrary and academic.

Socrates: Well, but what would it mean if we had two reasons to change?

Loej: I suppose it meant that the class did more than one thing.  It had two responsibilities.

Socrates: Right.  So either we planned for the class to have two responsibilities which we have decided is not a good idea, or we didn’t understand the class well enough in the first place because we didn’t see that there were two responsibilities – two reasons to change.

Loej:  I guess it makes sense.  Still, I can think of some cases this wouldn’t be good practice or good design.

Socrates: Sure. SOLID should help us think about good software design but they are principles of good design and not laws. Your domain model requirements should sometimes take precedence.

Loej:  So what you are saying is to keep this idea in mind as I code.  This will lend my design to looser coupling, easier testing, and smaller more focused objects.

Socrates:  Very good. Now go and meditate deeply on the letter S until we speak again.

Loej:  Yes master!

 
 

Socrates on SOLID: Motivation

17 Nov

This is the first in a series of (hopefully) amusing posts into Robert Martin’s SOLID principles.  It’s written as a dialog between Socrates and a student named Loej in the spirit of the dialectic method popularized by Plato.  I hope you find this enjoyable. 

The other posts in this series can be found below.

Socrates, who is the narrator of the dialogue.
Loej, who is but novice at the master’s feet.

Socrates: Welcome Loej. Today let us discuss the fundamental concern of software engineering. What is the chief concern of software engineering?

Loej: I know this one. It’s complexity.

Socrates: Indeed! And what is the chief cause of complexity in software development?

Loej: All those squiggles and curly things?

Socrates: Let me ask this another way. What is the one thing that customers always do?

Loej: Oh. They change their minds.

Socrates: Right! And when they change their minds, what do you do?

Loej: Try to talk them out of it.

Socrates: (Chuckles).

Loej: Right. Never works.

Socrates: So customers always change their minds. And what happens when they change their minds?

Loej: Usually we have to go back and make a lot of changes in the code.

Socrates: And what happens when you must change your code?

Loej: It depends on the size of the change, but usually it requires a lot of work just to try and not break anything. We have to tack a lot of stuff on. We have to break other stuff open.  One changes usually ripples through a lot of the code. It gets pretty messy.

Socrates: What do you mean by pretty messy?

Loej: More complex.

Socrates: And when you say tack stuff on and things ripple?

Loej: Well, sometimes we have something that depends on something else, and that something depends on something else, and so on. One change might need two more which might cause four more, and so on.

Socrates: So change can lead to a geometric increase in complexity.  We agree software engineering’s chief task is managing complexity. And we agree that a major contributor to complexity is change. So then our task must be to manage change in order to manage complexity.

Loej: But is change really the fault of developers? Isn’t this about poorly written specifications, lack of detailed requirements, customer’s needs shifting during the project, etc?

Socrates: Yes all of these things contribute to change, but they in turn are a results of a more fundamental aspect of software engineering. As Steve McConnell puts it software design is a wicked problem.

Loej: What’s a wicked problem?

Socrates: A wicked problem is one that is not fully understood until a solution has been formulated.

Loej: Then it’s impossible to solve!

Socrates: No. It is partially understood leading to partial solutions. Through the process of solving the problem, we gain better understanding of the problem.

Loej: Which then gives us the right solution!

Socrates: Sadly, no. There are no right solutions to wicked problems, only better solutions.

Loej: That’s lame.

Socrates: Indeed. So how do we get really good solutions if we must solve a problem to better understand it?

Loej: I guess we have to solve it many times, possibly over and over until we are done.

Socrates: In other words we must iterate. And what happens in each iteration?

Loej: We have to change the solution.

Socrates: Now we are getting somewhere. So change isn’t ancillary to software engineering is it?

Loej: No, it is a fundamental part of the process.

Socrates: Correct.

Loej: Well what can we do? How do we deal with change when it can be so disruptive?

Socrates: Ah! Now you are asking the right questions. Ponder what we have discussed and we shall talk again soon about some insight into this question called SOLID.