Principles Patterns Follow: Separation of Concerns

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:

  • The conceptual aspect: What it is
  • The specification aspect: How to use it
  • The implementation aspect: How it works
  • The creation aspect: How it is made
  • The selection aspect: How it is chosen
  • The workflow view: How it collaborates

Therefore,

  • The factory for an entity should make it but not use it.
  • The clients to an entity should use it but not make it.
  • Entities should be able to couple to each other conceptually, without also doing so concretely.
  • Two entities should be able to interact in different ways with the same third entity.

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.

Principles Patterns Follow: Dependency Inversion

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.

What to look for in frameworks and their providers

  1. An explicit starting point tailored for your organization.
  2. A statement of objectives for each part of the organization that allows for making local decisions in the global context.
  3. A support system to help you with challenges that arise so you need not reinvent the wheel
  4. A method of improving over time so you need not transcend the framework.
  5. A systems approach in guiding the adoption of the framework. This includes how to talk to the different roles in the organization.
  6. An increasing number of practices from which to choose without adding complexity to the framework

Does incorporating a few Agile practices into waterfall make waterfall Agile?

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.

Continue reading “Does incorporating a few Agile practices into waterfall make waterfall Agile?”

Principles Patterns Follow: Liskov Substitution

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.

Why the assumption that starting with a set start creates consistency is flawed

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.

Continue reading “Why the assumption that starting with a set start creates consistency is flawed”

Challenges I’ve learned how to solve by attending to Business Agility, Flow, and Lean

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:

Continue reading “Challenges I’ve learned how to solve by attending to Business Agility, Flow, and Lean”

Slower, Better, Cheaper- Why Scaled Learning Is Our Future and How to Get it Today

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.

Continue reading “Slower, Better, Cheaper- Why Scaled Learning Is Our Future and How to Get it Today”

Principles Patterns Follow: Open-Closed

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.