Month: July 2014

Scrum Methodology – Agile Software Methodologies

Posted on

Introduction

In our last post, we discussed Agile, its origins, basic concepts, and how it fits into the organization. While we often speak of Agile generically, we have to discuss the development methodologies that share the common philosophical beliefs of Agile.

Scrum

Scrum is the most prevalent of the Agile methodologies used in software development today, and rightfully so. With Scrum, development is executed via a series of short efforts called sprints. A sprint typically lasts from two to four weeks. The actual duration of each sprint is determined by the customer and the development team, but a sprint should not be too long. We’ll talk more that sprints later.

Scrum Terms and Concepts

Before we begin our discussion of Scrum, we first need to discuss some important terms and concepts associated with Scrum.

  • Scrum Team – the Scrum team is generally made up of less than 10 developers, business analysts, testers, etc. but can be larger if the product necessitates it. The team is totally self-sufficient and able to execute sprints effectively. In Scrum, roles such as architect, engineer, developer, etc typically go out the window in lieu of a sense of a team effort and an “all-for-one and one-for-all” mindset.
  • Scrum Master – the Scrum Master is a team member or manager whose primary responsibility is making the team as productive as possible. The Scrum master should be very well-versed in Scrum concepts and ideals and should insulate the team from outside influences and remove impediments that stand in the way of progress.
  • Daily Scrum – one of the key concepts of Scrum is the daily scrum. This is a quick, stand-up meeting of the development team. The purpose of the daily scrum is to keep the team on track on a daily basis by discussing the following three things for each team member: (1) what did you do yesterday? (2) what are you going to do today, and (3) do you have any impediments? The Scrum Master leads the daily scrum and ensures that the meeting is productive and stays on track.
  • Product Backlog – the Product Backlog is the all-inclusive list of every feature and component of every application that makes up the project as a whole.
  • Sprint Backlog – the Sprint Backlog is created from the Product Backlog each sprint during the Sprint Planning meeting. It is made up of all the tasks to be completed within a specified sprint.
  • Sprint Planning – the Sprint Planning meeting takes place before each sprint and is attended by the Scrum team members. The purpose of the Sprint Planning meeting is to define the work to be done by each person on the team for that sprint. Once this work has been defined and assigned, work items are moved from the Product Backlog to the Sprint Backlog.
  • Sprint Retrospective – one of the most effective ways to ensure continuous improvement within a Scrum team is to learn from mistakes. The Sprint Retrospective meeting, which takes place and the end of a sprint allows the team members to discuss the happenings of the prior sprint and identify things that could have been done better.
  • Sprint Review – the Sprint Review meeting is attended by the Scrum team and as many stakeholders as is necessary to demonstrate the new functionality and discuss its suitability to the needs of the business. The Sprint Review is kind of a show-and-tell where the team gets to present to the customer. This has always been my favorite part of a sprint! 🙂
  • Product Owner – the Product Owner is the project’s primary stakeholder and is usually a member of functional management within the organization.

Scrum in Practice

Now that we know the key terms associated with Scrum, let’s talk about how the Scrum development process actually works!

The necessary members of the team meet with the customer before work ever begins and identify to whatever extent possible the overall needs of the customer. These needs are not necessarily going to be truly complete and remember that Agile methodologies love change! But we do want to at least have a good understanding of what needs to be done to satisfy the customer’s needs and ensure that the results are in alignment with these needs.

Once we have identified the needs, we build the Product Backlog. As we discussed in the previous section, the Product Backlog is the full, all-inclusive list of the features needed. The business analysts, who are Scrum team members as well then do their best to decompose those needs into quantifiable requirements. A good requirement is a requirement that is testable, so it is imperative that the requirements are developed in such a way that the developers are able to understand them and further decompose specific tasks necessary to develop the requirement in its entirety.

Once we know (to the best of our ability) the Product Backlog, we can decide roughly how many sprints are needed to develop the functionality and assess the actual duration of each sprint. Based on the complexity of the features and the dynamics of the team, we may say that a three-week sprint is optimal, but sprints are typically from two to four weeks in length. Once we identify this duration, we generally want to stick to it and not deviate.

Before we begin a sprint, the Scrum team holds a Sprint Planning meeting. In this meeting, they review the Product Backlog and each developer decides just how much he/she can take on and complete and often high-level estimates are given based on the concept of shirt sizes (S, M, L, XL, XXL, etc). Other approaches are used, but the point of the Sprint Planning meeting is to determine and vote upon just how long the team thinks each item should take to develop and test. The Sprint Planning meeting may last from an hour to an entire day, but the outcome is the movement of work items from the Product Backlog to the Sprint Backlog and assignment of specific tasks to individuals.

When the sprint begins, the Scrum team works to develop and test the exact functionality defined in the Sprint Planning meeting. During the sprint, the Daily Scrum is instrumental in keeping each member of the team and the team as a whole on track and it is imperative that each team member knows what is going on around him/her and how the team as a whole is performing toward delivery of the feature(s) or functionality at the end of the sprint. The Daily Scrum should be as short in duration as possible, and most teams prefer to literally stand up during the meeting. Though the Scrum team should have a deep sense of camaraderie and sometimes a need to get off of the subject 🙂 the Scrum Master must keep things on track and make the team stay focused on the purpose of the meeting. During the Daily Scrum, the Scrum Master goes around the room and asks every team member the following questions:

  1. What did you do yesterday?
  2. What are you going to do today?
  3. Are there any impediments preventing you from getting things done?

If there are valid impediments, it is the Scrum Master’s responsibility to remove those impediments through whatever means necessary. Generally, the Scrum Master should be a person with adequate authority and credibility with the customer to be able to communicate with the necessary people to resolve any impediments encountered. This is vitally important to the successful implementation of Scrum!

Remember that as part of Agile, stakeholders are actively involved as often as is possible. It is not uncommon for stakeholders to be physically involved on a daily basis. During the sprint, developers may routinely do desk reviews with a stakeholder or stakeholders to verify proper functionality during development. A desk review is an informal, impromptu discussion/demonstration of a specific function with the customer.

At the end of a sprint, the team formally presents the new functionality to the customer and receives feedback in a Sprint Review meeting. If the sprint has been properly executed and the customer has been actively involved during development, the functionality that the customer sees should bring no surprises. It is not uncommon during Sprint Review meetings for the customer to engage in in-depth discussion about the business needs and it is also fairly common for there to be a realization than maybe some key element is missing. Thus, change is introduced into the mix and this is documented by the Scrum team. This change may likely go into the Product Backlog for inclusion in a future sprint.

Finally, at the end of each sprint, the Scrum team conducts a Sprint Retrospective meeting. This meeting is attended solely by members of the Scrum team and the purpose is to give the team the chance to reflect on anything and everything that can be done to function and perform more effectively going forward.

Advertisement

Agile Methodology – Using Agile to Develop Better Software and Reduce Risk

Posted on Updated on

Introduction

Imagine an enterprise software development project where the customer says “we are going to take a long time to get this done and we don’t expect to see any results for at least two years”. Can you imagine it? Me neither, and the truth is that it will probably never happen 🙂 So what is reality? In the real world of enterprise software development, the key for any development team is to provide maximum value to and work closely with the customer, to be able to build a culture of true ingenuity, and to be able to meet the customer’s changing needs in a way that there is minimal disruption, if any.

In the early days of software development, it was not uncommon for months to pass before any development began, and once development started, it could be months or years before any type of finished product was ready for testing. The requirements definition and gathering process was often very long, and in many cases the development team was isolated from the customer.

Once requirements were complete and development had begun, change was just not something that was easily entertained. Let’s keep in mind that concepts such as Continuous Integration and Configuration Management were unknown and use of source control repositories was not as mainstream as it is now. A change in requirements was just quite difficult to accommodate and was generally frowned upon.

The Agile Methodology

Agile was first introduced in February 2001 via the Agile Manifesto, a document created by a group of developers who met in Snowbird, Utah to discuss the principles behind a way to do lightweight software development. Since then, the Agile Methodology has grown and been widely adopted by software development teams and companies worldwide.

When we discuss Agile Methodologies, we must also mention Scrum, Lean Software Development, Kanban, Dynamic Systems Development Method (DSDM), and Extreme Programming, since these methodologies all share the same philosophy.

Agile - Scrum DSDM, Extreme Programming

In a nutshell, Agile is about communication, teamwork, collaboration, adaptability, iteration, feedback, and of course, agility! The development initiative is broken down into efforts of short duration and change is not only expected, it is embraced by all stakeholders. To successfully implement Agile, an organization must embrace its concepts and philosophies at all levels.

Agile provides a framework with which teams can maintain focus on rapidly delivering working software and providing true business value, even in environments where the technical and functional assets and landscape may vary or change routinely. We can say that Agile allows development teams to provide maximum business value through the delivery of truly valuable, working software that meets the business needs. How do we know that the software truly meets the business needs? Because all of the stakeholders are involved and quality and scope verification take place in short, iterative cycles. Deviations from the true purpose of a feature or piece of functionality can be identified quickly and corrected in an agile manner.

If we go back to the Agile Manifesto, there are 4 key points that it outlines.

It favors:

  • Individuals and interactions over processes and tools
  • Working software over comprehensive documentation
  • Customer collaboration over contract negotiation
  • Responding to change over following a plan

The key principles behind these points are outlined below (read these carefully):

  • Satisfy the customer through early and continuous delivery of working software
  • Change is welcomed, even late in the development process
  • Working software is delivered frequently, typically at intervals from two weeks to two months
  • Developers work directly with functional personnel/SMEs on a daily basis
  • Projects are built around motivated, capable people and they are given an environment that allows them to succeed
  • Face-to-face communication is critical
  • The primary measure of progress is working software
  • The development pace must be sustainable
  • Continuous attention to technical excellence and good design enhance agility
  • Simplicity is essential
  • The best architectures and designs emerge from effective, self-organizing teams
  • The team routinely reflects on past performance and seeks ways to do things better

If Agile is properly implemented, with buy-in from stakeholders at all levels of the organization, productivity and competitive advantage are maximized and cost is minimized. Of course Agile is not necessarily about reducing cost, but when properly implemented and managed that is a side effect that is very nice.

Let’s discuss the key points above in greater detail.

Favor Individuals and Interactions over Processes and Tools

The greatest processes and tools in the world are worthless without the right people effectively communicating and interacting. Regardless of the size or maturity of the organization, we should start with people then decide the appropriate processes and tools to make our Agile development more effective.

Favor Working Software over Comprehensive Documentation

In the days of waterfall development, I can remember the latter stages of larger projects being consumed with the creation of mounds of documentation! I remember working with teams of technical writers as they produced both functional and technical documentation for software deliverables. With Agile, any documentation that is created is usually created while development takes place. The rapid develop/release approach facilitates concurrency among developers, business analysts, and writers, and in an Agile environment the business analysts often produce the documentation.

Regardless of the use of Agile or not, it is rare that a customer not require some type of documentation and there is nothing wrong with that. But, in an organization that is truly Agile-oriented, working software is always the primary, core deliverable.

Favor Customer Collaboration over Contract Negotiation

Let’s face it, as long as development teams provide services for customers, there will always be contractual obligations. But when we use the term “contract negotiation” we imply an us versus them mentality and this is detrimental to the Agile process! For the Agile process to be effective, we need contractual vehicles that are flexible and that are developed and written to effectively handle change.

It is not uncommon to work with a client via a Firm Fixed Price (FFP) contract. From the customer’s perspective, FFP is preferable because it transfers risk to the service provider. In this case, Agile is still a valid development methodology IF the customer understands and truly embraces Agile concepts. The difficulty sometimes comes into play when the customer insists on defining functionality up front, forces the service provider to sign a contract whose estimates are based on these initial requirements, then tries to introduce scope creep as the project progresses. I sometimes refer to this as “agile under waterfall”, but Agile is still a good fit for such an endeavor. Obviously, a FFP contract is not the preferred vehicle under which to execute Agile, but it is still attainable if all stakeholders are well-versed in and embrace Agile concepts.

Favor Responding to Change over Following a Plan

Although detailed project plans and fancy Gantt charts are impressive, they are not useful with Agile. You read that right! Agile is based on release schedules where the prescribed functionality may be defined, but it is understood that it may change. Project progress within Agile is based on burndowns. Regardless of the actual functionality delivered, progress is still made over time. The total estimate may change due to newly-identified requirements or scope changes from the customer.

Agile and Risk Management

Prior to the emergence of Agile, a large number of software development projects failed or were cancelled with little or no working functionality in place. Teams often spent months or years working on a project with nothing tangible to show for their efforts. In many cases, projects were developed and delivered only to find that they did not meet the true needs of the business! Imagine after months or years of work and possibly millions of dollars of investment to discover that your needs haven’t even been met!

From the Project Management Institute’s (PMI) standpoint, Risk Management is a key knowledge area and something that is very high on the Project Manager’s priority list. All project managers should understand risk. It is just an inherent dynamic within any project and one that has to be understood, and either avoided or mitigated. So, what is risk? By its formal definition, risk is something that can or may occur and that could cause unexpected or unanticipated outcomes. Project managers know that risk is not always something negative. Opportunities are risks as well. But risk is something that, positive or negative, has to be identified, quantified, and managed. The situation, environment, project, people, etc determine when, where, and how risks are managed.

Agile reduces risk through through stakeholder involvement and rapid, iterative development and release. This means that evaluation of scope verification take place routinely, which effectively reduces risk.

Organizational Threats to Agile

The greatest single threat to Agile is management! More specifically, functional management with unrealistic expectations. In some organizations, Agile is nothing more than a buzzword because the stakeholders have not been educated in its fundamental concepts.

Earlier in this post, I mentioned the need for Agile to be understood and embraced by every stakeholder, from the top down. Without this understanding and support, it will likely fail or at the very least leave managers with a bad taste due to the fact that the development Project Manager tells them “we can certainly modify our approach and give you functionality X but requirement W is going to have to be pushed back to a future iteration.” In the case of FFP, requirement W may just have to drop off entirely!

With Agile, change is welcomed, even late in the development process, but in the case of FFP, it is possible that certain changes can significantly affect the project end date and thus necessitate contract extension.

Conclusion

So, Agile is a software development methodology that fosters rapid delivery of valuable, working software in an iterative manner. It values people and communication over processes and tools. It prefers working software over comprehensive documentation. It favors active and dynamic involvement of the customer and proper, effective identification of the true needs of the business over contract negotiation. It advocates the ability to nimbly respond to change, even late in the development process to following a detailed, pre-defined plan.

It can be argued whether or not it negates the need to perform Risk Management, but it is safe to say that with constant and active involvement of the customer and self-organizing, professional, competent, and productive development teams with a true dedication to the customer’s mission and a clear understanding of the customer’s needs, it can be enormously successful and a win-win for both the customer and the development team.

I will reiterate this final point because it is so hugely important – Agile MUST be understood and embraced by every member of the organization, from the CEO to the day-to-day tactical and functional personnel. Without this complete organizational buy-in and effective communication and interaction between all involved stakeholders, it will not be successful.

In the next post, we will discuss Scrum in detail.

Dependency Inversion Principle in C# – SOLID Design Principles – Part 5

Posted on Updated on

Overview

In our introduction to the SOLID Design Principles, we mentioned the Dependency Inversion Principle as one of the five principles specified. In this post we are going to discuss this design principle. Though a discussion of Dependency Injection and Inversion of Control are warranted here, we will save those topics for another post. I want to discuss the Dependency Inversion principle as simply and directly as possible.

Dependency Inversion Principle – Introduction

The Dependency Inversion Principle is a software design principle that provides us a guideline for how to establish loose coupling with dependencies from higher-level objects to lower-level objects being based on abstractions and these abstractions being owned by the higher-level objects.

The definition reads as follows:

  1. High-level modules should not depend on low-level modules. They should both depend on abstractions.
  2. Abstractions should not depend upon details. Details should depend upon abstractions.

These two items state that when building software, classes should be loosely-coupled based on abstractions (interfaces) and the details of the implementation should be encapsulated within the concrete classes that contain the logic. From top-down perspective, higher-level classes have only loose dependencies with lower-level classes.

What does that mean?

Dependency Inversion is about reversing the standard and conventional direction of dependencies from higher-level objects to lower-level objects by ensuring that the interfaces that dictate the functionality of the lower-level objects (i.e. the contracts that mandate what the lower-level objects must do) are owned by the higher-level objects. After all, if we consider our software holistically, the higher-level orchestrating objects are more valuable than the lower-level objects because they are the objects whose functionality we are most likely going to have the desire or need to extend.

Because the interfaces (contracts) that define what but not how the lower-level objects function are owned by the higher-level consumers, the higher-level objects do not rely upon how a lower-level object provides its functionality. Instead, they define what they need the lower-level objects to do and the lower-level objects provide the functionality/behavior demanded.

What Problems Are Solved with Dependency Inversion?

Poorly written software that is difficult to maintain and that has too many “hard” dependencies is a nightmare! How many times have we seen objects with numerous dependencies that cause us to shy away from trying to make changes? In my career I have seen more than I would care to remember!

When proper design principles are not considered early in the process, we often end up with code that is a tangled web of dependencies and when we are forced to make changes we often encounter unforeseen breakages that occur because of these dependencies.

When we implement the Dependency Inversion Principle, we reduce the coupling between “pieces” of code. When we build dependencies based upon interfaces (contracts), we introduce greater stability over time and we reduce the “hard” dependencies from concrete class to concrete class. Thus we reduce the possibility of introducing instability over the course of time. By coding to interfaces, we force our implementing classes to honor their agreements while the objects that consume them have no need to know how they honor them.

When we build software components that are reusable and consumable and that have external dependencies, we can find great value in the Dependency Inversion Principle’s objectives.

A word of caution – we cannot just program to interfaces and say that we have implemented Dependency Inversion! I will admit that this is a great idea in and of itself but by itself it does not give us Dependency Inversion. To truly realize the benefits, we have to ensure that the interfaces we use are owned and controlled by the higher-level objects. In other words, the top-level consumers own the contracts that must be honored by the lower-level providers.

So, using interfaces alone is NOT Dependency Inversion! Using interfaces to define what is needed by higher-level objects and writing lower-level objects to provide those needs by honoring the needs of the consumers in a way that the consumers have no reason to know anything about how the lower-level objects do what they do is moving in the right direction.

It is reasonable to say that classes are always going to have dependencies on other classes. You just can’t have properly-built object-oriented software without having dependencies between classes. But when changes are needed, it is very advantageous to make sure that changes have minimal impact on the overall functionality of the classes with dependencies on the classes changed. When we have tight coupling between classes, it is difficult to do this.

Let’s consider two types that we all know – an Engine and a Starter. We can say that an Engine has a dependency on a Starter as shown in the diagram below.

Dependency Inversion Principle

If we assume here that every Engine has a Starter that’s a pretty reasonable assumption. We can say that when we instantiate an Engine object we must also create a Starter object to start the Engine. With this model, the two are tightly-coupled.

But what if we have to change the starter and replace it with a different one? What if we have to change something in the Starter class? Such a change could potentially break the functionality of the Engine. How can we prevent that?

First, let’s make a statement: an Engine requires a component that is able to start it. It does not specifically require a Starter. With this in mind we can begin to decouple the two. Look at the next design with the understanding that the dotted gray line signifies ownership and control of types:

EngineStarter2

We’ve created an IStarter interface and since the Starter class implements this we are in good shape, right? Not exactly. Yes, the Engine having a dependency on the IStarter interface is an improvement since any class that implements IStarter can be used but we don’t have a hard dependency on Starter. We are moving in the right direction but we’re not there yet!

Let’s think about this from the standpoint of Dependency Inversion. To invert the dependency, the higher-level object must define and control the interface. Think about this: what if the Starter object changed in a way that forced a change to the IStarter interface? That could potentially break the Engine class’s logic because although it only expects a type that implements IStarter, the IStarter interface does not belong to the Engine class and is not defined based on what it needs. Therefore, the perceived loose coupling here is not real because the higher-level object (Engine) does not truly have control over the IStarter interface.

To implement Dependency Inversion, the higher-level modules must have control over the interfaces that they use to define their requirements for lower-level objects. Let’s revisit our logical design this way:

Dependency Inversion Principle

Now we’re getting somewhere! The Engine class owns the IStarter interface and thus controls what the classes that implement IStarter must provide. Nice! With this scenario, a change to a class that implements the IStarter interface that changes the interface is not valid.

So where is the inversion? If we go back to the first Engine/Starter diagram above, we see that changes within that scenario bubble from the bottom up. Changes to lower-level components force changes to higher-level components. With our new design, since the higher-level component owns and controls the interface, any change in the lower-level component that breaks its interface implementation is not valid unless the higher-level object allows it and the IStarter interface is changed as well. If the Engine must be changed in a way that affects the IStarter interface, the forcing of change is top down. In other words, the Starter must be changed as a result of a mandated change by the Engine. Make sense?

Another Example of Dependency Inversion

Let’s look at a simple example to which we can all relate. Think about the electric appliances in your house. They all have voltage requirements. In the U.S. we generally have 110, 220 and in some cases 440-volt power. If you’ve ever noticed, the plugs for each voltage are different.

In the context of Dependency Inversion, we can think of an appliance as a higher-level consumer and of the power supply in our house as a lower-level object that provides functionality needed by the appliance to operate. The appliance defines and owns its defines its needs and publishes those needs via its physical plug “interface”.

Though this sounds overly simple, it is a valid example of Dependency Inversion. So when we have an appliance that requires 220-volt service and we plug it into a 220-volt outlet, we expect for it to just work. We know that the plug is capable of providing 220-volt power because (1) the plug on the wall matches the plug on the appliance, and (2) the receptacle and wiring were put in place by a licensed electrician who knows and understands the electrical codes and the functional requirements of any device that uses 220-volt power. In other words, they power supply honors the “contract” between it and any device or appliance manufactured to use it.

From a software development perspective, we can say that the appliance is the higher-level object, the power cord and plug are the contract that defines what is needed by the higher-level object, and that the power supply itself is the lower-level object that is capable of honoring the needs of the consumer. We know that it can provide the needs of the consumer because in this case the physical characteristics of the receptacle (wall plug) tell us that it “implements the proper interface”. We can even say that the plug/receptacle connection is an abstraction. The appliance has no need to understand how the receptacle provides 220-volt power just that it does.

Refactoring Our Original Engine/Starter Design Sample

Now that we have covered Dependency Inversion and considered a couple of simple examples, let’s now return to the Engine/Starter design to which we’ve been applying SOLID design principles over the past few posts.

To recap this design, way back in the first post on the Single Responsibility Principle (Part 1) we originally started with a simple design that represented an Engine and its dependency on a Starter to provide ignition functionality. Our first design looked like this:

Single Responsibility Principle - SOLID Design Principles - Improved design

Then, in the second post on the Open-Closed Principle (Part 2) we refactored the design to make it open to extension but closed to modification. In the original design, we identified the three types of starters to be electric, pneumatic, and hydraulic. Because the implementation details of each unique type of starter were so different, we moved from a single Starter type to distinct types for each. We then created an interface named IStarter that they all implemented.

Open Closed Principle

Due to the fact that each starter type had internal functionality that was so different, to ensure that our derived (implemented) classes being substitutable for their base types (or interfaces), we segregated our interfaces as we see below. You can refer back to these posts for more information – Liskov Substitution Principle (Part 3) and Interface Segregation Principle (Part 4).

Dependency Inversion Principle - Sample class layout

Our starting code looks like this:

namespace SOLIDDesignPrinciples
{
    #region Base Classes

    public class Component : IComponent
    {
        public string Brand
        {
            get;
            set;
        }

        public string Model
        {
            get;
            set;
        }
    }

    #endregion Base Classes

    #region Interfaces

    public interface IComponent
    {
        string Brand { get; set; }
        string Model { get; set; }
    }

    public interface IStarter : IComponent
    {
        IgnitionResult Start();
    }

    public interface IElectricStarter : IStarter
    {
        Battery Battery { get; set; }
    }

    public interface IPneumaticStarter : IStarter
    {
        AirCompressor Compressor { get; set; }
    }

    public interface IHydraulicStarter : IStarter
    {
        HydraulicPump Pump { get; set; }
    }

    #endregion Interfaces

    #region Starter Types

    public class ElectricStarter : Component, IElectricStarter
    {
        public Battery Battery
        {
            get;
            set;
        }

        public IgnitionResult Start()
        {
            //code here to initiate the electric starter
            return IgnitionResult.Success;
        }
    }

    public class PneumaticStarter : Component, IPneumaticStarter
    {
        public AirCompressor Compressor
        {
            get;
            set;
        }

        public IgnitionResult Start()
        {
            //code here to initiate the pneumatic starter
            return IgnitionResult.Success;
        }
    }

    public class HydraulicStarter : Component, IHydraulicStarter
    {
        public HydraulicPump Pump
        {
            get;
            set;
        }

        public IgnitionResult Start()
        {
            //code here to initiate the hydraulic starter
            return IgnitionResult.Success;
        }
    }

    #endregion Starter Types

    #region Starter Support Components

    public class Battery : Component
    {
        public bool IsCharged
        {
            get
            {
                /*we could write logic here to handle the
                  validation of the battery's charge
                  for now, we will just return true */
                return true;
            }
        }
    }

    public class AirCompressor : Component
    {
    }

    public class HydraulicPump : Component
    {
    }

    #endregion Starter Support Components

    #region Enums

    public enum IgnitionResult
    {
        Success,
        Failure
    }

    #endregion Enums
}

Basically, this code representation of the different types of Starter types required to fulfill the ignition functionality for an Engine type can be summarized as follows:

  • There are three distinct types of Starters – ElectricStarter, PneumaticStarter, and HydraulicStarter.
  • Each Starter type implements the IStarter interface which defines the properties that are common to all Starter types, and each implements its specific interface type. The specific interface type is necessary because each type of starter is unique in its own operational requirement(s).
  • The IStarter interface implements the IComponent interface.
  • Each Starter type inherits the Component base class and each Starter interface implements the IStarter interface.
  • The lower-level components required by the Starter types also inherit Component (since they are components too).

If we include the Engine itself in our dependency chain, we have a clear dependency hierarchy. Let’s look at it from an abstraction standpoint:

  • Engine has a dependency on a Starter, or rather anything that is an IStarter.
  • An IStarter can be an IElectricStarter, IPneumaticStarter, or IHydraulicStarter.
  • An IElectricStarter has a dependency on a Battery.
  • An IPneumaticStarter has a dependency on an AirCompressor.
  • An IHydraulicStarter has a dependency on a HydraulicPump.

Hold on a minute! Weren’t these supposed to all be abstractions? Yes they were, so let’s take a look at the lower-level objects and do some further decomposition.

If we are going to build dependencies based on abstractions all the way down the chain, we need to think a little more about what I will call the second-level objects. In the case of a Battery, in reality there are about five distinct types of automobile batteries! So to provide a proper abstraction from the ElectricStarter to a Battery, we must make this dependency an abstraction too.

If we refer to this resource,  we lean more about our previous statement that there are five distinct types of car batteries – just check it out if you are interested :). To be correct in our design and to make our code as closed to modification as possible, we must define each type as a distinct type within our design. These distinct types will then be set as dependencies of the ElectricStarter abstractly.

To do this, we first make the Battery class an abstract base class.

public abstract class Battery : Component, IBattery
    {
        public bool IsCharged
        {
            get;
            set;
        }

        public abstract void EvaluateCharge();
    }

We made the EvaluateCharge() method abstract to force our derived Battery classes to override its functionality.

We are also going to create specific battery type classes and although the actual logic behind how to validate the battery’s charge may vary significantly based on the type of battery, each type must still offer the EvaluateCharge() functionality. Make sense?

So here are our new classes for each type of battery:

public class WetFloodedBattery : Battery, IBattery
{
    public override void EvaluateCharge()
    {
        //logic here to evaluate the charge
        this.IsCharged = true;
    }
}

public class CalciumCalciumBattery : Battery, IBattery
{
    public override void EvaluateCharge()
    {
        //logic here to evaluate the charge
        this.IsCharged = true;
    }
}

public class VRLABattery : Battery, IBattery
{
    public override void EvaluateCharge()
    {
        //logic here to evaluate the charge
        this.IsCharged = true;
    }
}

public class DeepCycleBattery : Battery, IBattery
{
    public override void EvaluateCharge()
    {
        //logic here to evaluate the charge
        this.IsCharged = true;
    }
}

public class LithiumIonBattery : Battery, IBattery
{
    public override void EvaluateCharge()
    {
        //logic here to evaluate the charge
        this.IsCharged = true;
    }
}

If you look at these classes and say “they’re all the same!”, yes they are. Imagine that the charge validation logic is very different for each distinct type. That logic is not the point of this example, so we are not touching that. For this sample, all of the overridden methods just set the IsCharged property value to true 🙂 We have segregated each distinct type to honor the Single Responsibility Principle and give our classes only one reason to change. You can refer back to that post if you would like.

Next, to keep things simple, we have made our ElectricStarter class generic. When we create a new instance of an ElectricStarter we will have to inject an IBattery type into the constructor. This way we are using Constructor Injection to inject the ElectricStarter’s battery dependency upon creation. We will cover Dependency Injection in another post, so don’t get stuck on what we just said here. Just understand that we are requiring every instance of an ElectricStarter to be supplied with an instance of an IBattery type.

Let’s take a look at our new ElectricStarter class:

public class ElectricStarter<T> : Component, IElectricStarter<T>
    where T : IBattery
{
    public ElectricStarter(T battery)
    {
        this.Battery = battery;
    }

    public T Battery
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        this.Battery.EvaluateCharge();
        if (this.Battery.IsCharged == true)
        {
            return IgnitionResult.Success;
        }
        else
        {
            return IgnitionResult.Failure;
        }
    }
}

We should also note that we have made our IElectricStarter interface generic.

public interface IElectricStarter<T> : IStarter
{
    T Battery { get; set; }
}

So far so good. Now let’s return to our Engine class and make some changes.

First, we will make the Engine.Start() accept the IStarter instance.

public interface IEngine : IComponent
{
    IgnitionResult Start(IStarter starter);
}

#endregion Interfaces

#region Engine

public class Engine : Component, IEngine
{
    public IgnitionResult Start(IStarter starter)
    {
        return starter.Start();
    }
}

#endregion Engine

If we then flip over to the Program.cs class of our sample C# Console application, and add code to instantiate an Engine, a starter, and a battery and run it we will see a successful engine start!

namespace SOLIDPrincipleSamples
{
    class Program
    {
        static void Main(string[] args)
        {
            IEngine engine = new Engine();

            IBattery battery = new LithiumIonBattery();
            IElectricStarter<IBattery> starter = new ElectricStarter<IBattery>(battery);

            IgnitionResult result = engine.Start(starter);

        }
    }
}

So now that we have defined this design, are working with dependencies based on abstractions, and have an Engine that we can start, let’s consider the ownership of the interfaces we have defined from a Dependency Inversion standpoint.

First, remember that the higher-level objects must own the interfaces. If we consider our model from the top down, we start with the Engine.

The Engine depends on a Starter, or more appropriately an IStarter. Since we created interfaces for each of the three types of starters (IElectricStarter, IPneumaticStarter, IHydraulicStarter) the Engine should own and have control over those interfaces.

Each type of Starter has a dependency on some lower-level object. In the case of the ElectricStarter, there is a dependency on a Battery, or should we say an IBattery. As we built our code we discovered that there are actually five different kinds of car batteries and we created classes for each and each class implemented the IBattery interface. Therefore, the ElectricStarter should own the IBattery interface. We could go so far as to say that the Engine could conceivably own it as well and that would not necessarily be wrong, but we want to segregate ownership where it truly belongs.

If you want to create your own C# console application and play with this a little more, the code for the Engine, starters, and all other classes/interfaces is below. You can copy and paste this into a single .cs file if you want and experiment.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SOLIDDesignPrinciples
{
    #region Base Classes

    public class Component : IComponent
    {
        public string Brand
        {
            get;
            set;
        }

        public string Model
        {
            get;
            set;
        }
    }

    public abstract class Battery : Component, IBattery
    {
        public bool IsCharged
        {
            get;
            set;
        }

        public abstract void EvaluateCharge();
    }

    #endregion Base Classes

    #region Interfaces

    public interface IComponent
    {
        string Brand { get; set; }
        string Model { get; set; }
    }

    public interface IStarter : IComponent
    {
        IgnitionResult Start();
    }

    public interface IElectricStarter<T> : IStarter
    {
        T Battery { get; set; }
    }

    public interface IPneumaticStarter : IStarter
    {
        AirCompressor Compressor { get; set; }
    }

    public interface IHydraulicStarter : IStarter
    {
        HydraulicPump Pump { get; set; }
    }

    public interface IBattery : IComponent
    {
        bool IsCharged { get; set; }
        void EvaluateCharge();
    }

    public interface IEngine : IComponent
    {
        IgnitionResult Start(IStarter starter);
    }

    #endregion Interfaces

    #region Engine

    public class Engine : Component, IEngine
    {
        public IgnitionResult Start(IStarter starter)
        {
            return starter.Start();
        }
    }

    #endregion Engine

    #region Starter Types

    public class ElectricStarter<T> : Component, IElectricStarter<T>
        where T : IBattery
    {
        public ElectricStarter(T battery)
        {
            this.Battery = battery;
        }

        public T Battery
        {
            get;
            set;
        }

        public IgnitionResult Start()
        {
            this.Battery.EvaluateCharge();
            if (this.Battery.IsCharged == true)
            {
                return IgnitionResult.Success;
            }
            else
            {
                return IgnitionResult.Failure;
            }
        }
    }

    public class PneumaticStarter : Component, IPneumaticStarter
    {
        public AirCompressor Compressor
        {
            get;
            set;
        }

        public IgnitionResult Start()
        {
            //code here to initiate the pneumatic starter
            return IgnitionResult.Success;
        }
    }

    public class HydraulicStarter : Component, IHydraulicStarter
    {
        public HydraulicPump Pump
        {
            get;
            set;
        }

        public IgnitionResult Start()
        {
            //code here to initiate the hydraulic starter
            return IgnitionResult.Success;
        }
    }

    #endregion Starter Types

    #region Starter Support Components

    public class WetFloodedBattery : Battery, IBattery
    {
        public override void EvaluateCharge()
        {
            //logic here to evaluate the charge
            this.IsCharged = true;
        }
    }

    public class CalciumCalciumBattery : Battery, IBattery
    {
        public override void EvaluateCharge()
        {
            //logic here to evaluate the charge
            this.IsCharged = true;
        }
    }

    public class VRLABattery : Battery, IBattery
    {
        public override void EvaluateCharge()
        {
            //logic here to evaluate the charge
            this.IsCharged = true;
        }
    }

    public class DeepCycleBattery : Battery, IBattery
    {
        public override void EvaluateCharge()
        {
            //logic here to evaluate the charge
            this.IsCharged = true;
        }
    }

    public class LithiumIonBattery : Battery, IBattery
    {
        public override void EvaluateCharge()
        {
            //logic here to evaluate the charge
            this.IsCharged = true;
        }
    }

    public class AirCompressor : Component
    {
    }

    public class HydraulicPump : Component
    {
    }

    #endregion Starter Support Components

    #region Enums

    public enum IgnitionResult
    {
        Success,
        Failure
    }

    #endregion Enums
}

Points to Ponder

One more thing to think about with Dependency Inversion is how abstraction is handled within the various layers of an application or object hierarchy. I have written numerous application frameworks in my time as an architect and developer, and one thing that holds true when writing this type of code is that you find yourself within the various levels writing abstract code with the intent of it being used concretely at some later point in time. It is necessary to rely upon generic abstractions within lower levels and allowing the ultimate consumers/clients to determine the exact implementation details. With Dependency Inversion, we can effectively build objects that perform the necessary tasks without knowing the exact details of each task at the time we write them. This idea may sound a bit counterintuitive at first, but it is something to think about as you explore this topic more deeply.

Additional Links

The SOLID Design Principles
The Single Responsibility Principle (SRP)
The Open-Closed Principle (OCP)
The Liskov Substitution Principle (LSP)
The Interface Segregation Principle (ISP)
The Dependency Inversion Principle (DIP)

Single Responsibility Principle in C# – SOLID Design Principles – Part 1

Posted on Updated on

Overview

In our introduction to the SOLID Design Principles, we mentioned the Single Responsibility Principle as one of the five principles specified. In this post we are going to dive into this design principle with a very simple example in C#.

The Single Responsibility Principle states that a class should have only one reason for change. The greater the number of responsibilities, the more reasons a class will have for change. Seems pretty simple, right? When you consider it for what it is, it is pretty simple.

I am most definitely NOT a mechanic, and I do not claim to know a great deal about combustion engines, but I think that a subset of an engine’s functionality is a great way to illustrate the SOLID design principles. The engine in your automobile is a marvel of modern engineering and has been designed to function optimally with each component having minimal dependencies on other components. An engine is maintainable because the various parts/components are easily removed and replaced. This is how our applications should be written.

So let’s consider an automobile engine from the standpoint of the starter mechanism. In case you don’t know, your engine has a component called a starter that is attached to the engine, has electrical connections to allow it to draw power from the battery, and when you engage your ignition switch via a key or pushbutton, the starter is energized. When it is energized, it forces the engine to turn over and the combustion process begins. If you would like to learn more about how a starter works, here is a great article 🙂 Haha. So let’s move on, shall we?

IMPORTANT: For the sake of simplicity, we are going to assume that for this example, the one hard rule that will not ever change is the fact that there will always be a Starter object and a Battery object associated with an Engine. If we don’t make this assumption and declare it as a “rule”, the scope of our design changes could make the illustration of the concept overly-complicated and I really want to keep it simple here and discuss the principle in the simplest terms possible.

Furthermore we are going to use our design in this post to continue to apply SOLID design principles one by one.

Design #1 – Not so Good

Let’s suppose that we wanted to represent an Engine’s ignition/starter functionality in a few C# classes. If we didn’t understand the Single Responsibility Principle, we might build our classes similarly to this:

Engine Ignition Initial (Invalid) Class Design - Single Responsibility Principle

Based on the design shown above, let’s consider this code:

public class Engine
{
    public IgnitionResult Start(Starter starter, Battery battery)
    {
        //we would put code here to handle the logic for checking
        //whether or not the batter is charged

        //then we check the result of our logic
        if (battery.IsCharged)
        {
            //we could put logic here to handle
            //the actual ignition process
            return IgnitionResult.Success;
        }
        else
        {
            //uh oh! the battery is not charged
            //Failure!
            return IgnitionResult.Failure;
        }
    }
}

public class Starter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }
}

public class Battery
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public bool IsCharged
    {
        get;
        set;
    }
}

public enum IgnitionResult
{
    Success,
    Failure
}

Let’s think about this code as it is written. It makes sense that we would have an Engine class, a Starter class, a Battery class, and an IgnitionResult enum. So far so good. But when we look in the Engine class and read the Start() method, we can see that there may be more than one reason why the Engine class would have to be changed. It is responsible for too many things. Any logic associated with how to start the engine is contained within the Start() method as is the “validation” of determining whether or not the battery is charged.

Consider the following questions:

  1. What if we installed a different type of Battery and the logic associated with verifying its charge state changed?
  2. What if we installed a different type of Starter and the logic associated with how it actually works internally changed?

If either of these things changed we would have to modify our Engine class to accommodate the change(s). The key point here is that the Engine class has more than one responsibility and per the Single Responsibility Principle this is not good.

Design #2 – Better!

Now let’s reconsider our design, remembering that each class should have not more than one reason for change.

First, the logic for actually handling the Starter’s ignition process should be moved to the Starter class and the Starter itself should contain a Start() method which will be invoked by the Engine’s Start() method.

Next, the battery charge validation logic should be moved to the Battery class since the battery itself knows better than anything how to validate its own state. Sounds sensible, right?

Let’s take a look at the improved design:

Single Responsibility Principle - SOLID Design Principles - Improved design

So what did we do? First, we removed anything to do with the “internal workings” of the Starter and the Battery out of the Engine class and into each respective class. Now, based on the assumption we made above that stated in this scenario an Engine will always have exactly one Starter and exactly one Battery, the Engine class has only one reason for change as do the Starter and Battery classes.

Keep in mind that as we get into the other SOLID Design Principles we are going to begin abstracting things so that we will have a truly “pluggable” design but for now we are working directly with concrete Starter and Battery objects. That will change as we move through the other principles and we will begin to see continuous improvement!

We left the Brand and Model properties in the Starter and Battery classes. Obviously we can see that this is not an ideal design, but remember – we are focusing on the Single Responsibility Principle for now! These properties are inconsequential now.

Based on the design shown above, our new code looks like this:

public class Engine
{
    public IgnitionResult Start(Starter starter, Battery battery)
    {
        return starter.Start(battery);
    }
}

public class Starter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public IgnitionResult Start(Battery battery)
    {
        //since the Battery class now contains that actual charge validation
        //logic, the Starter merely checks the value of that property
        //and the Battery takes care of the rest
        if (battery.IsCharged)
        {
            //we can put the ignition logic here
            return IgnitionResult.Success;
        }
        else
        {
            return IgnitionResult.Failure;
        }
    }
}

public class Battery
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public bool IsCharged
    {
        get
        {
            //we can put logic here for the battery
            //to validate its charge and return
            //a result
            return true;
        }
    }
}

public enum IgnitionResult
{
    Success,
    Failure
}

So we have a better design from the standpoint of the Single Responsibility Principle. The goal is to modify all of our classes so that each class has one and only one reason for change. Since the example is very simple, accomplishing this is pretty easy. As designs become more complex, the amount of time to create the correct design can grow tremendously but the time required is very well worth it long-term because it will yield a much more maintainable and effective design overall.

In the next post, we will dive into the Open-Closed Principle. See the links below for all posts related to the SOLID Design Principles.

The SOLID Design Principles
The Single Responsibility Principle (SRP)
The Open-Closed Principle (OCP)
The Liskov Substitution Principle (LSP)
The Interface Segregation Principle (ISP)
The Dependency Inversion Principle (DIP)

Open-Closed Principle in C# – SOLID Design Principles – Part 2

Posted on Updated on

Overview

In our introduction to the SOLID Design Principles, we mentioned the Open-Closed Principle as one of the five principles specified. In this post we are going to dive into this design principle and work with a very simple example in C#.

The Open-Closed Principle states that modules should be open for extension but closed for modification. Simply stated, this means that we should not have to change our code every time a requirement or a rule changes. Our code should be extensible enough that we can write it once and not have to change it later just because we have new functionality or a change to a requirement.

If you consider the number of times that code is changed after an application makes its first ‘release’ and you begin to quantify the actual time (and expense) associated with repeated changes to code over the life of the application, the actual development cost is probably not going to surpass the ongoing maintenance costs.

Think about it, when you change existing code, you have to test the changes. We all know that 🙂 But to be complete in your implementation, you also have to perform regression testing to ensure no unforeseen bugs have been introduced either as direct or indirect results of your new changes! In short, we don’t want to introduce breakages as the result of modifications – we want to extend functionality.

But let’s be realistic for a second. To interpret the Open-Closed Principle to say that we can NEVER change our code is a bit over-the-top in my opinion. I can tell you from years of practice that this is simply never going to happen! There will always be code changes as long as there are requirements changes – that’s just the way it is. You can however greatly minimize the actual code changes needed by properly designing applications in the beginning, and the Open-Closed Principal is one of the five SOLID design principles that allow you to do that.

In the last post, we began building a few classes that represent the starter/ignition system of an automobile engine. As is the theme for all posts here, we kept the example scenario very simple and kept the code simple to illustrate the design principle.

We are going to take the code that we wrote in the Single Responsibility Principle post and modify it further to illustrate the Open-Closed Principle. We have removed the Battery class because in the context of this discussion it is really not significant and introduces unnecessary noise.

So let’s get going! For more background on how we arrived at the design below, refer back to the the previous post.

The code looks like this:

public class Engine
{
    public IgnitionResult Start(Starter starter)
    {
        return starter.Start();
    }
}

public class Starter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //logic to initiate start
        return IgnitionResult.Success;
    }
}

public enum IgnitionResult
{
    Success,
    Failure
}

Let’s consider this design, and also consider the two notions described by the Open-Closed Principle. Modules that conform are:

  1. Open for Extension – the behavior can be extended in a variety of ways as the requirements change
  2. Closed for Modification – existing, stable code should not be changed

With these things in mind, let’s discuss what we need to do with our Engine/Starter scenario to allow us to minimize changes going forward.

Open-Closed Principle – C# Example

So to get started, let’s take the code from the last post (shown above) and add a little meat to it! We purposely left the body of the Start() method of the Starter class kind of bare because we weren’t concerned with that when we discussed the Single Responsibility Principle. But now we are very interested in that so let’s add a StarterType enum, a StarterType property to our Starter class, and let’s add some dummy logic within the Start() method to make this all work. Remember, this initial code is NOT going to adhere to the Open-Closed Principle – we are modifying the original code in preparation for this.

Design #1 – Not so Good

First, we will add the StarterType enum:

public enum StarterType
{
    Electric,
    Pneumatic,
    Hydraulic
}

Then we will add a property to the Starter class:

public StarterType StarterType
{
    get;
    set;
}

Finally, we will add some logic to our Starter class’s Start() method that performs some action based on the StarterType specified.

public IgnitionResult Start()
{
    //initiate the starter based on the StarterType
    if (this.StarterType == SOLIDPrincipleSamples.StarterType.Electric)
    {
        //initiate the electric starter
        return IgnitionResult.Success;
    }
    else if (this.StarterType == SOLIDPrincipleSamples.StarterType.Pneumatic)
    {
        //initiate the pneumatic starter
        return IgnitionResult.Success;
    }
    else
    {
        //initiate the hydraulic starter
        return IgnitionResult.Success;
    }
}

Okay, we know that we could have one of three types of starters – electric, pneumatic, or hydraulic. Seems reasonable that we would write an if block that checks the type and performs some type of action, right? Well, not really. What if our requirements change and we have to now accommodate another type of starter that we hadn’t anticipated? Well, we will have to change our Starter class, and we really don’t want to do that!

So what can we do?

Design #2 – Much Better

The solution is actually pretty straightforward and it involves thinking in terms of extending NOT modifying! Here’s how we can do that:

First, let’s rethink our Starter class. Instead of having a single concrete Starter class, we will create a concrete class for each type of starter and consider each as a distinct type within our design. To bring all those together, we will create an interface which we will name IStarter. Each of our three starter types will implement this interface and each will contain its specific logic for initiating the engine start functionality.

Our new design looks like this:

Open Closed Principle

So here are our new classes and our new interface:

public class Engine
{
    public IgnitionResult Start(IStarter starter)
    {
        return starter.Start();
    }
}

public interface IStarter
{
    string Brand { get; set; }
    string Model { get; set; }
    IgnitionResult Start();
}

public class ElectricStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the electric starter
        return IgnitionResult.Success;
    }
}

public class PneumaticStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the pneumatic starter
        return IgnitionResult.Success;
    }
}

public class HydraulicStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the hydraulic starter
        return IgnitionResult.Success;
    }
}

public enum IgnitionResult
{
    Success,
    Failure
}

So now we have three concrete classes, one for each type of starter, a single interface which is implemented by each of the three concrete starter classes, and our StarterType enum is no longer needed! With this design, if we need to add a new type of Starter, we do NOT have to change our existing code but instead we can add a new class for that type of starter and change the consuming code very slightly to expect the new type where needed. We are not going to dive into a Factory pattern in this post, but that is an effective way to handle the Open-Closed Principle.

So to recap, if we write code that is open for extending but closed to modification we are much better off! The Open-Closed Principle provides us guidance for how to accomplish this. Now keep in mind that this was a simple example, but as I say all the time, simple examples are the best ways to illustrate virtually any development topic.

In the next post, we will dive into the Liskov Substitution Principle. See the links below for all posts related to the SOLID Design Principles.

The SOLID Design Principles
The Single Responsibility Principle (SRP)
The Open-Closed Principle (OCP)
The Liskov Substitution Principle (LSP)
The Interface Segregation Principle (ISP)
The Dependency Inversion Principle (DIP)

Liskov Substitution Principle in C# – SOLID Design Principles – Part 3

Posted on Updated on

Overview

In our introduction to the SOLID Design Principles, we mentioned the Liskov Substitution Principle as one of the five principles specified. In this post we are going to dive into this design principle and work with a very simple example in C#.

As you study the SOLID Design Principles, you will notice there is a great deal of overlap among the individual principles. While discussing the Liskov Substitution Principle, we are going to take a quick dive into the Interface Segregation Principle as well, but not overly so as the next post will discuss that more deeply. We will however take a look at how to segregate interfaces in pursuit of not violating the Liskov Substitution Principle.

Formal Definition

The Liskov Substitution Principle states that if for each object m1 of type S there is an object m2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when m1 is substituted for m2 then S is a subtype of T.

Useful Definition

Let’s reword the definition above to actually be understandable. In a nutshell, the Liskov Substitution Principle  includes two main points:

  1. Derived classes should be substitutable for their base classes (or interfaces).
  2. Methods that use references to base classes (or interfaces) have to be able to use methods of the derived classes without knowing about it or knowing the details.

So what in the world does all that mean? It means that our derived classes (or implementing classes) cannot modify or break the functionality dictated by their base classes or implemented interfaces.

Let’s just dive in and take a look at the Engine/Starter class design that we have been using for the first two posts on the SOLID Design Principles.

As of the completion of our post on the Open-Closed Principle, here is our design:

Open Closed Principle

 

We created separate concrete classes for the different types of Starters used to start our Engine and we made each class implement the IStarter interface. This allowed us to migrate our code to be open to extending but closed to modification.

So far so good, right? Well, maybe not!

Let’s look at the code from the last post that matches the class diagram above:

public class Engine
{
    public IgnitionResult Start(IStarter starter)
    {
        return starter.Start();
    }
}

public interface IStarter
{
    string Brand { get; set; }
    string Model { get; set; }
    IgnitionResult Start();
}

public class ElectricStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the electric starter
        return IgnitionResult.Success;
    }
}

public class PneumaticStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the pneumatic starter
        return IgnitionResult.Success;
    }
}

public class HydraulicStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the hydraulic starter
        return IgnitionResult.Success;
    }
}

public enum IgnitionResult
{
    Success,
    Failure
}

Design #1 – Not Good At All!

This all works fine in the simple example because we are assuming that all types of Starters are the same. But what if they aren’t? What if, for example an ElectricStarter makes use of a Battery, a PneumaticStarter makes use of an AirCompressor, and a HydraulicStarter requires a HydraulicPump object to function? Well, if we were hell-bent on keeping our IStarter interface we could do something like this:

First we would have to create classes for Battery, AirCompressor, and HydraulicPump. Then we would add properties for each to the IStarter interface. Let’s just do it and see how it looks 😦

public interface IStarter
{
    string Brand { get; set; }
    string Model { get; set; }
    Battery Battery { get; set; }
    AirCompressor Compressor { get; set; }
    HydraulicPump Pump { get; set; }
    IgnitionResult Start();
}

public class ElectricStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public Battery Battery
    {
        get;
        set;
    }

    public AirCompressor Compressor
    {
        get
        {
            throw new NotImplementedException("An Electric Starter does not use an AirCompressor.");
        }
        set
        {
            throw new NotImplementedException("An Electric Starter does not use an AirCompressor.");
        }
    }

    public HydraulicPump Pump
    {
        get
        {
            throw new NotImplementedException("An Electric Starter does not use a HydraulicPump.");
        }
        set
        {
            throw new NotImplementedException("An Electric Starter does not use an HydraulicPump.");
        }
    }

    public IgnitionResult Start()
    {
        //code here to initiate the electric starter
        return IgnitionResult.Success;
    }
}

public class PneumaticStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public Battery Battery
    {
        get
        {
            throw new NotImplementedException("An PneumaticStarter does not use a Battery.");
        }
        set
        {
            throw new NotImplementedException("An PneumaticStarter does not use an Battery.");
        }
    }

    public AirCompressor Compressor
    {
        get;
        set;
    }

    public HydraulicPump Pump
    {
        get
        {
            throw new NotImplementedException("An PneumaticStarter does not use a HydraulicPump.");
        }
        set
        {
            throw new NotImplementedException("An PneumaticStarter does not use an HydraulicPump.");
        }
    }

    public IgnitionResult Start()
    {
        //code here to initiate the pneumatic starter
        return IgnitionResult.Success;
    }
}

public class HydraulicStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public Battery Battery
    {
        get
        {
            throw new NotImplementedException("A HydraulicStarter does not use a Battery.");
        }
        set
        {
            throw new NotImplementedException("A HydraulicStarter does not use an Battery.");
        }
    }

    public AirCompressor Compressor
    {
        get
        {
            throw new NotImplementedException("A HydraulicStarter does not use an AirCompressor.");
        }
        set
        {
            throw new NotImplementedException("A HydraulicStarter does not use an AirCompressor.");
        }
    }

    public HydraulicPump Pump
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the hydraulic starter
        return IgnitionResult.Success;
    }
}

public class Battery
{
}

public class AirCompressor
{
}

public class HydraulicPump
{
}

public enum IgnitionResult
{
    Success,
    Failure
}

Alright! So we added the properties to our IStarter interface and implemented them in each concrete class, so all is well, right? Not exactly.

Although we aren’t necessarily violating the Open-Closed Principle, we are in violation of the Liskov Substitution Principle and honestly this is just really not a good design! Although we implemented all of the possible properties of our classes in our IStarter interface, the classes that implement our interface are NOT substitutable for it. Why not? Because their behavior is not consistent across the different types of starters. Although the interface is in place, the implementing classes don’t truly implement it when in play.

Consider this: suppose we create an instance of an ElectricStarter and use an instantiated Battery object to set its Battery property? That works pretty well. But now let’s imagine another developer consuming our code and seeing the Compressor property as being a usable public property for the ElectricStarter and trying to either get it or set it. What happens? A NotImplementedException is thrown 🙂 This is not consistent behavior! The interface contains a property for an AirCompressor, a developer consuming our code can reasonably expect that to work, despite the fact that any of us “reasonable” people might look at that and ask “why would an ElectricStarter need an AirCompressor?” 🙂

So you may ask “why not just remove the NotImplementedExceptions in the properties that don’t matter for each class and just go with it?” The answer to that is easy – any time you see properties or methods within derived (or implementing) classes that do not do what their name suggests (or what they should be doing) that is a big red flag or a not-so-good design! As responsible designers/developers, we must handle invalid conditions and operations correctly and deliberately and not place properties or methods in our interfaces or classes that surprise their consumers by what they do or how they behave – make sense? Thus instead of having a property or method that actually does nothing is not a good idea and the presence of such items signals trouble!

The Liskov Substitution Principle is very focused on extrinsic public behavior and the fact that consumers expect predictable and constant behavior for published/implemented interfaces. Our design does NOT provide that!

Design #2 – Much Better

To rectify this flawed design, we need to think about another SOLID design principle – the Interface Segregation Principle. If we think about our IStarter interface as the starting point, we can consider the following things:

  1. The properties/method that are common to ALL starter types are: Brand, Model, and Start().
  2. The properties that are specific to each starter type are: Battery, Compressor, and Pump.

With these things in mind, the first thing that we need to do is to make use of not one interface but four! Take a look at our revised interfaces below:

public interface IStarter
{
    string Brand { get; set; }
    string Model { get; set; }
    IgnitionResult Start();
}

public interface IElectricStarter : IStarter
{
    Battery Battery { get; set; }
}

public interface IPneumaticStarter : IStarter
{
    AirCompressor Compressor { get; set; }
}

public interface IHydraulicStarter : IStarter
{
    HydraulicPump Pump { get; set; }
}

I picked the interface segregation as our starting point because it sets the stage for the changes that need to be made to the concrete classes. This design is far superior from the standpoint of the Liskov Substitution Principle!

So now let’s rewrite our Starter classes to implement their respective interfaces:

public class ElectricStarter : IElectricStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public Battery Battery
    {
        get;
        set;
    }       

    public IgnitionResult Start()
    {
        //code here to initiate the electric starter
        return IgnitionResult.Success;
    }
}

public class PneumaticStarter : IPneumaticStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public AirCompressor Compressor
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the pneumatic starter
        return IgnitionResult.Success;
    }
}

public class HydraulicStarter : IHydraulicStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public HydraulicPump Pump
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the hydraulic starter
        return IgnitionResult.Success;
    }
}

We now have a design that makes far more sense. Yes, we went from one interface to four, but this is not a bad thing when we consider the SOLID Design Principles collectively, which is a very good thing to do.

In the next post, we are going to dive more deeply into the Interface Segregation Principle. See the links below for all posts related to the SOLID Design Principles.

The SOLID Design Principles
The Single Responsibility Principle (SRP)
The Open-Closed Principle (OCP)
The Liskov Substitution Principle (LSP)
The Interface Segregation Principle (ISP)
The Dependency Inversion Principle (DIP)

 

Interface Segregation Principle in C# – SOLID Design Principles – Part 4

Posted on Updated on

Overview

In our introduction to the SOLID Design Principles, we mentioned the Interface Segregation Principle as one of the five principles specified. In this post we are going to dive into this design principle with a very simple example in C#.

In the last post on the Liskov Substitution Principle, we utilized the Interface Segregation Principle to refactor our code. The code that we write in this post will be very simple as well and will take that code and introduce another segregation of our interfaces. I generally do not write posts that are “recaps” of previous posts, but our implementation from the last post certainly warrants a “recap” in this one.

The Interface Segregation Principle states that clients (classes) should not be forced to implement interfaces that they do not use. Well this certainly sounds reasonable, doesn’t it?

So if we start with our original design from the Liskov Substitution Principle post, here is our original design and code:

Open Closed Principle

public class Engine
{
    public IgnitionResult Start(IStarter starter)
    {
        return starter.Start();
    }
}

public interface IStarter
{
    string Brand { get; set; }
    string Model { get; set; }
    IgnitionResult Start();
}

public class ElectricStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the electric starter
        return IgnitionResult.Success;
    }
}

public class PneumaticStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the pneumatic starter
        return IgnitionResult.Success;
    }
}

public class HydraulicStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the hydraulic starter
        return IgnitionResult.Success;
    }
}

public enum IgnitionResult
{
    Success,
    Failure
}

In our last post, instead of a single Starter class, we created a distinct type for each type of Starter – electric, pneumatic, and hydraulic. Then we realized that in actual implementation, each type of starter had a different requirement for the object it used to actually work. The ElectricStarter utilized a Battery, the PneumaticStarter utilized an AirCompressor, and the HydraulicStarter utilized a HydraulicPump. When we actually wrote the code needed to make these work, we realized that our single interface just did NOT make sense. See the code below.

public interface IStarter
{
    string Brand { get; set; }
    string Model { get; set; }
    Battery Battery { get; set; }
    AirCompressor Compressor { get; set; }
    HydraulicPump Pump { get; set; }
    IgnitionResult Start();
}

public class ElectricStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public Battery Battery
    {
        get;
        set;
    }

    public AirCompressor Compressor
    {
        get
        {
            throw new NotImplementedException("An Electric Starter does not use an AirCompressor.");
        }
        set
        {
            throw new NotImplementedException("An Electric Starter does not use an AirCompressor.");
        }
    }

    public HydraulicPump Pump
    {
        get
        {
            throw new NotImplementedException("An Electric Starter does not use a HydraulicPump.");
        }
        set
        {
            throw new NotImplementedException("An Electric Starter does not use an HydraulicPump.");
        }
    }

    public IgnitionResult Start()
    {
        //code here to initiate the electric starter
        return IgnitionResult.Success;
    }
}

public class PneumaticStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public Battery Battery
    {
        get
        {
            throw new NotImplementedException("An PneumaticStarter does not use a Battery.");
        }
        set
        {
            throw new NotImplementedException("An PneumaticStarter does not use an Battery.");
        }
    }

    public AirCompressor Compressor
    {
        get;
        set;
    }

    public HydraulicPump Pump
    {
        get
        {
            throw new NotImplementedException("An PneumaticStarter does not use a HydraulicPump.");
        }
        set
        {
            throw new NotImplementedException("An PneumaticStarter does not use an HydraulicPump.");
        }
    }

    public IgnitionResult Start()
    {
        //code here to initiate the pneumatic starter
        return IgnitionResult.Success;
    }
}

public class HydraulicStarter : IStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public Battery Battery
    {
        get
        {
            throw new NotImplementedException("A HydraulicStarter does not use a Battery.");
        }
        set
        {
            throw new NotImplementedException("A HydraulicStarter does not use an Battery.");
        }
    }

    public AirCompressor Compressor
    {
        get
        {
            throw new NotImplementedException("A HydraulicStarter does not use an AirCompressor.");
        }
        set
        {
            throw new NotImplementedException("A HydraulicStarter does not use an AirCompressor.");
        }
    }

    public HydraulicPump Pump
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the hydraulic starter
        return IgnitionResult.Success;
    }
}

public class Battery
{
}

public class AirCompressor
{
}

public class HydraulicPump
{
}

public enum IgnitionResult
{
    Success,
    Failure
}

Upon reviewing this code more, it became painfully apparent that it was quite bad and required some refactoring. So, per the Interface Segregation Principle, we broke out the interfaces that we actually needed and went from one interface to four interfaces. As a result, each Starter class implemented its own interface that interface had only what was needed for that type. Nice! Our final code from the last post is below:

public interface IStarter
{
    string Brand { get; set; }
    string Model { get; set; }
    IgnitionResult Start();
}

public interface IElectricStarter : IStarter
{
    Battery Battery { get; set; }
}

public interface IPneumaticStarter : IStarter
{
    AirCompressor Compressor { get; set; }
}

public interface IHydraulicStarter : IStarter
{
    HydraulicPump Pump { get; set; }
}

We picked the interface segregation is our starting point because it sets the stage for the changes that need to be made to the concrete classes.

So then we rewrote our Starter classes to implement their respective interfaces:

public class ElectricStarter : IElectricStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public Battery Battery
    {
        get;
        set;
    }       

    public IgnitionResult Start()
    {
        //code here to initiate the electric starter
        return IgnitionResult.Success;
    }
}

public class PneumaticStarter : IPneumaticStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public AirCompressor Compressor
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the pneumatic starter
        return IgnitionResult.Success;
    }
}

public class HydraulicStarter : IHydraulicStarter
{
    public string Brand
    {
        get;
        set;
    }

    public string Model
    {
        get;
        set;
    }

    public HydraulicPump Pump
    {
        get;
        set;
    }

    public IgnitionResult Start()
    {
        //code here to initiate the hydraulic starter
        return IgnitionResult.Success;
    }
}

And in doing that, we were introduced to the Interface Segregation Principle and used it to help us adhere to another principle. The overlap among the SOLID design principles is so nice!

In the next post, we are going to dive more deeply into the Dependency Inversion Principle. See the links below for all posts related to the SOLID Design Principles.

The SOLID Design Principles
The Single Responsibility Principle (SRP)
The Open-Closed Principle (OCP)
The Liskov Substitution Principle (LSP)
The Interface Segregation Principle (ISP)
The Dependency Inversion Principle (DIP)

 

 

SOLID Design Principles

Posted on Updated on

In software development, principles differ from patterns in the sense that where patterns represent complete, identifiable, repeatable solutions to common problems, principles are objective, factual statements that can be made about code and the manner in which it is constructed and the overall design of an implementation. In other words, patterns refer to code scenarios while principles refer to qualities of code and these qualities are useful in identifying the value of the code.

In this post, we are going to be introduced to Bob Martin’s SOLID design principles. These principles have been around for a long time, and it is immeasurably important for every object-oriented developer to understand them and use them in making day-to-day design decisions. It is not that uncommon to see developers dive into development tasks by writing code first and considering architecture and design second. A good developer though inverts this scenario and considers a sound design before writing the first line of code! This prevents undue code maintenance pain later and allows for the development of better applications through and through.

Consideration of design principles is extremely important throughout a development effort, and failure to make the proper considerations can have a devastating effect on the development of the application and the application’s usefulness, performance, and maintainability.

What are the SOLID Design Principles?

In this section, we are going to outline and briefly discuss each of the five design principles. In subsequent posts we will dive into each principle in more detail. The five SOLID design principles are listed below:

  1. The Single Responsibility Principle (SRP) – this principle states that there should never be more than one reason to change a class. This means also that a given class should exist for one and only one purpose.
  2. The Open-Closed Principle – this principle states that modules should be open for extension but closed for modification. This seems a bit unclear at first until you realize that you can change an object’s behavior by either using abstractions, implementing common interfaces, and from inheritance from common base classes or extending abstract base classes.
  3. The Liskov Substitution Principle – this principle, introduced by Barbara Liskov, simply-stated means that derivative classes have to be substitutable for their base classes. If we think about this for a minute, we can see that this also means that any class that implements a specific interface can be replaced by any other class that implements that interface. In other words, it can be substituted for the original class. Furthermore, a derived class must honor the ‘contract’ set by its super class.
  4. The Interface Segregation Principle (ISP) – this principle states that objects should not be forced to implement interfaces that they do not use. Though this may sound obvious based on the wording, in practice it really means that interfaces should be finely-grained and not specific to the classes for which their implementation is intended.
  5. The Dependency Inversion Principle (DIP) – this principle states that higher-level classes should not depend upon lower-level classes but that both should depend on abstractions. Furthermore, these abstractions should not depend on concrete details but rather on abstractions as well.

Though each principle can be discussed individually, we should understand that no single principle should exist or be applied by itself. They should all be considered as part of the design process. In the following posts, we will dive into each principle in detail and take a look at some simplified code examples that illustrate each one.

The Single Responsibility Principle (SRP)
The Open-Closed Principle (OCP)
The Liskov Substitution Principle (LSP)
The Interface Segregation Principle (ISP)
The Dependency Inversion Principle (DIP)

Enterprise Architecture – What is an Enterprise Architect and Where in the Organization Does He Belong?

Posted on Updated on

What is Enterprise Architecture?

We probably all know the textbook definition of an Enterprise Architect to be something like this: “An Enterprise Architect is responsible for aligning business objectives and IT in a strategic way…“. But what is really happening in the world of business when it comes to Enterprise Architecture? How are companies evolving and making the most effective use of their Enterprise Architecture staff? Where in the overall hierarchy of the organization does (and should) Enterprise Architecture reside? What trends are we seeing in the business world to give us any indication of the true answer? How does the EA work with the CIO and/or CTO and should that role of EA fall under either of these?

In a survey that I read a few months ago (and I cannot remember the source), the author mentioned that as of 2012, less than 5% of Enterprise Architects reported directly to a higher company executive such as the CEO or COO, and the percentages of EAs reporting to CIOs and CTOs were around 45% and 15% respectively. These are estimates of course, but the numbers are interesting.

As an Enterprise Architect myself, I have had numerous discussions with people at various levels of the organizations in which I’ve worked and for whom I was contracted, and the opinions regarding the true role of the Enterprise Architect vary greatly. Furthermore, you will find no shortage of disagreement if you google the discussion and read the opinions.

With all of this in mind, let’s discuss Enterprise Architecture and the true role of the Enterprise Architect in the organization.

What are the Qualities of a Good Enterprise Architect?

First, let’s talk about just what type of person it takes to be a successful Enterprise Architect. An Enterprise Architect should be:

  • Technically competent in multiple areas – a good EA must be technically-competent and respected. For an EA, technical competence is no trivial endeavor. He or she must be well-versed in enterprise software, both COTS and internally-developed, must be very knowledgeable of network and server infrastructure, and must be able to effectively communicate with and assist the technical folks who manage all of the company’s IT assets. Beyond that, the EA must be very knowledgeable of not just the company, but the industry (or industries) in which the company competes. The EA must recognize the environmental factors that affect both the overall strategy and the day-to-day operations.
  • A tested problem solver – this goes without saying but it is important to mention it as a critical quality. The successful Enterprise Architect must be able to quickly understand problems that are often not well understood by many and not easily identifiable. He or she must be able to quickly recognize patterns and behaviors, both environmental and internal.
  • A great communicator – He or she should be able to communicate technical concepts to non-technical people clearly, concisely, accurately, and in my opinion, eloquently. The EA should be able to effectively communicate ideas and concepts to large groups of people and to individuals. The people with whom the EA interacts on a daily basis will be of varying knowledge and skill levels, and will have unique perspectives on their specific job roles and the overall operation of the business.
  • An effective salesperson – changing the way a company does business is no small task and many times salesmanship is required to convince stakeholders. Beyond that, the EA must be able to “sell” the wholistic vision to people at all levels of the organization and inspire each person to embrace that vision.
  • Detail-oriented – as they say “the devil is in the details”. Although Enterprise Architecture is a strategic endeavor, an EA should be able to ensure success through great attention to detail. Strategy should not lack detail in any way.
  • Objective and Deliberate – the EA should be a “voice of reason” and should be able to objectively formulate and implement the Enterprise Architecture skillfully and deliberately.
  • A “Sponge” – don’t laugh 🙂 An EA should be able to absorb and assimilate an enormous amount of information and knowledge quickly and effectively. He or she should, in reality understand the mission of the business as well or better than all of the individual stakeholders.
  • A proactive facilitator – the EA is the driving force behind change.
  • Able to think at all levels – the EA must be able to formulate the “master plan” and understand the details of its implementation well enough to accurately tailor the plan to the true needs of the business as a whole AND to ensure the correct and optimal orchestration of all of the smaller “pieces” of the architecture.

If you read the items above and conclude that the Enterprise Architect is a “jack of all trades” you are correct and that is why an organization must have the right person or people for the job! A successful EA should have the mindset of both strategic management and technical implementation. In other words, he should be able to craft the strategy, communicate it to stakeholders, and be able to actually implement it or oversee its implementation both functionally and technically.

Over the past several years, as companies began to realize the importance of making the right technology decisions and cohesiveness of the overall “master plan”, the role of Enterprise Architect grew more and more important. Today this need is greater than ever. With constant acquisitions and the disparate technologies that those often introduce into a company’s existing mix of IT resources, it is imperative for companies to position themselves in such a way that IT is a distinct competitive advantage, NOT a necessary evil.

I recall many years ago being told by a CEO that he wasn’t sure exactly what the IT folks did, but he knew they occupied a large part of one wing of the building and he just knew that they did “stuff” to keep the “systems” working. Wow! This type of thinking will not yield success in today’s business climate!

What is the Outcome of Successful Enterprise Architecture?

An organization that has correctly implemented an effective Enterprise Architecture will benefit in several ways. Though this list is certainly not exhaustive, I see these as the most noteworthy.

  • Greater profitability – correctly streamlined and enhanced business processes cost less, require fewer human resources, and should directly contribute to increased profitability.
  • Reduced risk – a successful Enterprise Architecture should reduce a company’s exposure to risk through proper identification of the risks themselves, implementation of systemic measures to mitigate those risks, and overall greater process integrity which will yield greater robustness and thus reduced composite risk.
  • Greater agility – a company that is nimble and able to quickly react to market changes and external influences is better able to compete and survive. Successful Enterprise Architecture allows a company to do this by being properly positioned both technically and functionally to adapt to any type of change.
  • Better decision-making – EA affords a company the ability to more proactively undertake proper impact analysis and simply be better able to make the right decisions quickly. One of the obvious benefits of better decision-making is cost reduction. Who wouldn’t want that?

So does it really come down to having a “wholistic vision” just for sake of having it? Of course not. Having such an overarching view of the organization yields tangible, quantifiable benefits that are definitely not limited to the few items I listed above.

The Big Question – Where Should Enterprise Architecture Reside in the Organization?

So finally, the obvious question! Where does the role of EA belong? Is it a subset of IT, is it a business/functional endeavor, or is it a higher-level activity?

The Enterprise Architect role is one that often raises eyebrows in companies and organizations that are not truly serious about Enterprise Architecture. The EA is generally well compensated and is thus the target of discussions by those who do not understand his or her true value. This is unfortunate, but true in many organizations. In many smaller organizations, the Enterprise Architect is one of the the highest paid members of IT.

Senior management must drive change from the top. The degree of change that is often necessary within an organization commonly brings with it varying degrees of pain. People are generally comfortable with the status quo and as we all know, resist change. It’s human nature. But to be successful, the Enterprise Architect must overcome resistance and effectively craft the master plan and implement it. This requires the unwavering support of both senior and functional management.

An Enterprise Architect who reports directly to a CIO or CTO is often seen as an IT resource and viewed by functional management as just another “IT guy” (or girl). Ultimately, the CIO or CTO makes the decisions, in collaboration with other senior managers, and thus the Enterprise Architect is viewed as a “technical advisor”. The notion of anything beyond that often creates conflict among other departments who want to feel that they have the final say. But does this really work? Does it tie the Enterprise Architect’s hands unnecessarily?

Should the Enterprise Architect report directly to a senior manager? If so, should it be the CIO or CTO – should it be the CEO or COO? Is the Enterprise Architect a member of IT or should the position be more overarching? How much control/authority should the EA be given? Is an EA merely an “advisor” or something more? Though these are good questions, the answers probably depend on the company itself.

The perception that an EA is too “powerful” can sabotage the mission of Enterprise Architecture within an organization. But at the same time, the EA must have a clear sense of vision and drive to propel both him and the organization forward. So what is the acceptable balance?

Discussion

I welcome discussion on this post! Please feel free to give me your thoughts and be as honest as possible. I know that this is a great source of debate in many organizations and although the business climate is changing, I am curious how the role of Enterprise Architect will evolve with it.

 

SOAP Serialization with C# and .NET

Posted on Updated on

In the previous post, we discussed binary serialization with C# and .NET. In this short article we are going to dive into some specific examples of use of the SoapFormatter class to SOAP serialize objects to XML and deserialize from XML back into objects.

We will discuss SOAP a little later in this article 🙂

SOAP Serialization with the SoapFormatter class

To get started, let’s create a simple class, add some attributes to help us control how properties are serialized, then we’ll serialize and deserialize the object.

To get started, let’s create a C# Console Application that we will call SoapSerializationSample.

Create the Soap Serialization Sample Console project
Create the Soap Serialization Sample Console project

Next, we will add a class to the project. We will call this class Sample.

Let’s now add two properties – Name and Value as shown below then decorate the class with the Serializable attribute.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SoapSerializationSample
{
    [Serializable]
    public class Sample
    {
        public string Name
        {
            get;
            set;
        }

        public Int32 Value
        {
            get;
            set;
        }
    }
}

As you can see, this class is very simple and is a great starting point for examining SOAP serialization.

The Serializable attribute signals the .NET runtime that instances of this class can be serialized. To use serialization, this attribute must be in place at the class level.

Before we write the serialization code, let’s first add the references shown in the illustration below:

System.Serialization.Runtime References
System.Serialization.Runtime References

Next, let’s add the following using statements to our Program class:

using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;

In our Program.cs class’s Main() method, we are going to write some simple code that uses the SoapFormatter to serialize an instance of our Sample object into a Soap XML stream.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Soap;

namespace SoapSerializationSample
{
    class Program
    {
        static void Main(string[] args)
        {
            //create an instance of our Sample class
            //which we will serialize below
            Sample sample = new Sample();
            sample.Name = "John Nelson";
            sample.Value = 44;

            //create a FileStream to accept the output
            FileStream fileStream = new FileStream(@"c:\temp\MySoapFile.dat", FileMode.Create);

            //create a SoapFormatter to serialize the object
            SoapFormatter formatter = new SoapFormatter();

            //serialize the object to the .dat file
            formatter.Serialize(fileStream, sample);
        }
    }
}

When we press F5 and run the application, the SoapFormatter serializes the Sample object to our MySoapFile.dat file. If we open this file in Visual Studio, we see something that looks like this:

SoapFormatter XML Output
SoapFormatter XML Output

So, some of you are probably looking at this output and screaming “this is NOT well-formed XML!” and you are right! This file does not contain an xml declaration does not contain opening and closing xml tags. Though an in-depth discussion of SOAP is well beyond the purpose and scope of this article, it will be beneficial to briefly discuss the parts of a SOAP message.

What is SOAP?

Soap is an acronym for Simple Object Access Protocol. It is basically an XML-based protocol for transmitting data between computers and is designed for for data communication via the internet and provides the transport mechanism for web services. SOAP is language and platform independent.

SOAP Message Structure

SOAP messages are encoded as XML documents. These documents begin with a mandatory <Envelope> element and may or may not contain a <Header> element. The <Body> element is mandatory for all SOAP messages, so we would expect to always see that. A <Fault> element may or may not be contained within the <Body> element and is used to provide information about exceptions or errors that may have occurred while the message was processed.

<Envelope> Element

The <Envelope> element is the start and end of the message. The entire SOAP message is contained within the <Envelope> element. Every <Envelope> element must contain exactly one <Body> element – no exceptions! The <Envelope> will change if the version of the message changes.

<Header> Element

<Header> elements are optional within the <Envelope> element and there can be multiple <Header> elements in a SOAP message.

<Body> Element

The <Body> element contains the actual data being transmitted in the SOAP message. You can think of it as the “guts” of the message or the payload of the message.

<Fault> Element

If you have ever worked with WCF, you are familiar with the FaultExceptions. When an error occurs during processing by a web service, information pertaining to that error can be encapsulated within a <Fault> block. If a <Fault> element is included in a SOAP message, there can only be one.

Learning More About SOAP

If you are interested in learning more about the SOAP standard, try this link.

Deserializing with the SoapFormatter

Deserializing with the SoapFormatter is as simple as serializing. See the code below:

//create a FileStream to open the .dat file
FileStream fileStream = new FileStream(@"c:\temp\MySoapFile.dat", FileMode.Open);

//create a SoapFormatter to deserialize the object
SoapFormatter formatter = new SoapFormatter();

//serialize the object to the .dat file
Sample deserializedSample = (Sample)formatter.Deserialize(fileStream);

//show the object properties
Console.WriteLine("The deserialized object:");
Console.WriteLine(String.Format("Name: {0}", deserializedSample.Name));
Console.WriteLine(String.Format("Value: {0}", deserializedSample.Value.ToString()));

Console.Read();

When we press F5 and run our application, we see the values of our object displayed in the console window:

SoapFormatter.Deserialize()
SoapFormatter.Deserialize()