Common reasons given for why Agile fails:
- Management wasn’t involved
- Teams weren’t motivated
- People didn’t follow the framework
- Agile is hard and complex
- What I never hear is – “our frameworks are insufficient for the task.”
Common reasons given for why Agile fails:
Good design separates things that change for independent reasons. This is often called the “Separation of Concerns” (Edsger Dijkstra) and applies to many different aspects of design, process, and analysis.
Here are some examples of aspects of an entity that should ideally be handled separately from one another:
By “entity,” I mean class, method, function, subsystem, or anything that creates behavior in a system. Patterns separate concerns in various ways, depending on what the concerns are.
In 1996, Robert Martin postulated, “High level modules should not depend on low level modules; both should depend on abstractions. Abstractions should not depend on details. Details should depend upon abstractions.”
When objects interact, they do so through some kind of interface. An interface is always an abstraction of some kind. The first part of this principle is about making sure these abstractions are not tied to specific implementations.
But there is more to consider. How is an interface created? Based on what? What should the methods of a service look like, and what should the signatures of those methods be?
In both cases, we should avoid basing an interface on how the entity functions (its implementation). Rather it should be based on how it will be used (the conceptual, or abstract view of the behavior in question).
Test-first promotes this because the first time an interface is accessed, it is by the test and also before the implementation has been created. The influence must be from use. The test is the first user/client of the behavior.
The patterns all display this kind of dependency inversion, and therefore each is an example of why this principle is so crucial in keeping systems cleanly maintainable.
Of course not. But yet we hear people infer that incorporating a few Lean practices into Scrum makes it Lean. It doesn’t.
Waterfall is not just based on its practices, but on its mindset of being able to predict and plan out ahead. Putting an Agile practice into waterfall will likely improve things, but it doesn’t make it Agile. The reason is that waterfall =mindset + practices. The practices are done within the context of the mindset.
Barbara Liskov (1987) stated, “Clients that use base classes must be able to use objects of derived classes without changing” (paraphrased).
When a class is derived from a base class, traditionally we call this an “is-a” relationship. But Liskov suggests we should instead consider it to be a “behaves-like” relationship and, when this determined to be untrue, then perhaps inheritance is being misused.
One place where I saw this in action was in scheduling. The system began with the concept of an “Event,” which had a start date, end date, start time, and end time.
Later, a “Day-Long Event” was added by sub-classing “Event” since a “Day-Long Event is an Event.” However, the Day-Long Event was altered such that the start and end times were locked at midnight-to-midnight since a “day is a 24-hour period.”
This caused problems when support for different time zones was added. Day-Long Events that were 12 AM-12 AM in one zone were 9 PM – 9 PM in others, spanning two days… A 24-hour period is not always a day; they did not “behave” the same way and therefore were not substitutable.
The patterns rigorously avoid this kind of mistake.
The two most popular Agile frameworks today suggest a preset starting method. Scrum with cross-functional teams and SAFe with Essential SAFe.
Both have the rationale that people need to start in a well-defined way and abide by it until they learn more. SAFe also promotes that consistency of practices is needed across the organization.
Business Agility sets the why and goal. Flow and Lean both provide insights on what to do and how you are doing.
Here are some challenges they help overcome:
There are two types of classroom training – one where the instructor dumps information into the students minds. The second when labs are involved so that students are mostly interacting with the instructor or doing work.
This post refers to the first type.
Classroom training is centuries old. The recent fad of adding exercises and games helps, but doesn’t change the fact that the students forget 80-90% of what they’ve learned after just a week. Training is also focused on a canned solution instead of people’s problems.
The “Open-Closed Principle” was coined in 1988 by Bertrand Meyer, based on an idea put forth earlier by Ivar Jacobsen.
It states, “Software entities (such as classes, modules, functions) should be open for extension, but closed to modification.”
What does this mean? It means that one aspect of strong design is that it allows new functions, features, behaviors, etc. to be added to a system in such a way that the previously existing code does not have to be altered.
Most experienced developers will tell you they would much prefer to make something new rather than change something old. This is because they have experienced both things and have found that making new things is less difficult, less dangerous, less time-consuming, and in general is something they feel more confident about.
How can this principle be achieved? You can make a system open-closed in many different ways, depending on what you want to be able to add later by cleanly plugging in a new entity.
Each design pattern follows open-closed in a different way, about a different thing or set of things. Understanding this is an interesting way to distinguish each pattern from the others. I will examine this aspect of each pattern as I explore it.