var blog = new ThoughtStream(me); RSS 2.0
 Tuesday, October 28, 2008

In my last post, I talked about the idea of encapsulation and using it to ensure that our business rules were enforced correctly. What I didn't talk about, though, was the second half of the conversation that my coworker and I had, concerning the patent -> consultation relationship. It turns out that we had the relationship wrong. That's not to say that patients don't have consultations, but that the logical model we were traveling with had an incorrect perspective and was causing us to create some very ugly workarounds in various parts of the system. What really stuck out in my mind, though, was not the idea that we had the model wrong, but how we came to the conclusion of the model being wrong. It has become apparent to me, upon reflection of the conversations and situation as a whole, that design smells are not always evidenced by design related activities, if ever.

A Persistent Problem - Duplicate Redundancy

After some initial coding of the patient -> consultation relationship, we start working on the persistence model via NHibernate. What we have is a patient with a collection of consultations - this is easy to map with NHibernate's one-to-many capabilities. We also have a CurrentConsultation property which needs to be mapped. This property is mapped to the same Consultation table, but only pull one specific consultation based on the business rules that state the current consultation is chronologically the most recent and has not ending date set.

After some thought, we found that there were a few possibilities for handling the CurrentConsultation property in our current model:

  1. Create a "CurrentConsultation" object that is mapped to the Consultation table and use a "where" class attribute in the NHibernate mapping that would limit the returned result
  2. Create a "CurrentConsultation" object that is mapped to a CurrentConsultation view and have the view coded to return the correct consultation object
  3. Add a CurrentConsultationId field to the Patient table, as a foreign key to the Consultations table, and map to the existing Consultation object

After some additional thought, though, we found that each of these solutions has a few significant problems that were going to cause a lot of trouble.

Options 1 and 2

Both of these options have the problem of duplicating business rules into more than one language and location. We would either have the business rules of what constitutes the current consultation in the NHibernate mapping (the 'where' attribute) or in a database view, in addition to the already existing code. Changing the rule would mean changing a minimum of two locations where that rule is handled. This is a bad idea no matter how you look at it.

Both of the options have also created a duplication of knowledge from the concept of a Consultation by creating a "CurrentConsultation" class and a separate NHibernate map for it. We would have the original Consultation class and the new CurrentConsultation class both representing the same data, making an artificial distinction in our code. Again, this is a bad idea. We don't want duplication of these logical concepts. We're also not dealing with a bounded context or any other logical separation of concerns at this point, so there is no need to separate the concept of a consultation into multiple classes.

Option 3

This doesn't appear to have the duplication issue in code, but there is a potential for duplication of data. When we get down to the implementation of NHibernate, we could easily cause duplicate data in the consultation table by saving the current consultation class. We might be able to get around this by not cascading the saves of the current consultation property, but then we'd be forced to ensure the consultation collection was persisted prior to the patient so that we could update the current consultation object's id before saving the patient. Both of these problems sound like a serious pain to me. I'm betting it's possible, but I'm also betting that it would be a nightmare of trial and error to get it right and a lot more code than we should really have to write.

Changing Perspectives

As Joe Ocampo pointed out in the comments of my original post, we had a problem in our system that was really caused by our lack of correct perspective in the situation. Rather than forcing the idea of a patient being the root aggregate in this situation, causing us a lot of headache and frustration in trying to model our persistence layer, a simple change in how we looked at the situation helped us solve the persistence problem and greatly simplified how the application worked.

Joe's comment (with some formatting added):

"One thing I like to challenge developers with when I teach DDD is to flip the aggregate to determine if the model is sound.

I know this is only an example but work with me here.  You indicated you are dealing with a medical system.  We can assume there are certain entities such as Patient, Consultations, Doctor and Practice. In your example you created a model where the patient is the aggregate root for consultations but what if the Doctor simply asked what consultations do I have today?  In this paradigm the Practice is the aggregate root and Consultations are aggregate within where Patient is an aspect of the consultation.  The code would look something like this.

consultations = practiceService(IConsultationService).GetConsultationsFor(doctor);

This also allows the consultation service to encapsulate its own logic for creating a consultation for creating a consultation. You can’t get any closer than that :-)

consultationService.CreateConsultationFor(patient).with(doctor).at(date);

The point I am trying to make is be careful of aggregate roots.  Once you go down that path it is really difficult to back the train up and break it apart."

Though our actual implementation was different, this was the same basic conclusion that we had come to - our perspective on the situation was simply wrong. When we stepped back from the problem and realized that the consultation was the primary focus of the situation, and that a nurse or doctor would be the primary user of that portion of the system, it became rather obvious that our aggregate was in dire need of rework.

A Reflective Perspective

What we ended up with was a Patient object that dealt with all of it's demographics information, billing information, etc, without a CurrentConsultation property or even a Consultations list. Then, on the the separated Consultation object, we added a child property of Patient. Once we realized that our Consultation object was the primary focus and made this distinction in our code, we also realized that the Patient object was carrying far too much information around the system. We found that we actually had two very distinct concepts of a patient, determined by two very distinct bounded contexts.

  • In the 'Billing' context, we needed all of the address , billing, and other demographics information about the patient - who they are, where they live, what their insurance is, etc. The existing Patient class filled this need.
  • In the 'Consultations' context, we did not need anything from the Billing context, except for the person's name and patient id. What we really care about in the consultations is medical information about the patient - their current prescriptions, allergies, past medical care, etc. So, we created a ' patient' class to represent these needs.

These changed allowed for a much more clearly defined model that was truly reflective of the systems needs. We could easily see the difference between a 'billing' patient and a 'medical' patient, and we were able to code each of these areas of the system without the concerns bleeding into each other. Essentially, we decoupled the system at a module level, not just at a class level.

We also found that the NHibernate mapping problems suddenly went away. Since the Consultation class had a child of Patient, it was a simple many-to-one mapping with no strange sequencing or duplicate data issues. In the screens that deal with the consultation directly, we load the consultation as the aggregate root and go from there. In the screens that need to show patient consultation history, we did a simple query and returned all of the consultations for the given patient. Again, we found a way to decouple our system - this time, at the persistence model.

Design Smells: Not Just A Design Problem

In the end, we were able to recognize a serious design smell in our system - not by the design itself, though. After all, the original code had encapsulated the needs quite well. But, as it turns out, it was a bad encapsulation at a higher level. It wasn't until we started working with the model we had created, specifically trying to persist the model, that we realized our design was not right.

This change was a huge breakthrough for us, not necessarily in the code or the system that was being built, but in how we look at our systems and our domain models. The realization that design smells are often evidenced not by the design itself, but by how the design is used in the infrastructure and other supporting roles of the system, has had a profound impact on how we look at system design. I'm now seeing areas of different systems that are encapsulated incorrectly, at a higher level than class design. Recognizing the problem is the first step - and we're now working to rearrange and invert these models to more accurately reflect reality.

Pay attention to the pain that your application, infrastructure and other supporting services are causing you. You may be staring at evidence of a design problem, without realizing it.



_________________________________
Cross Posted From LostTechies.com
Tuesday, October 28, 2008 2:45:45 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Analysis and Design | Data Access | Design Patterns | Domain Driven Design | NHibernate | Principles and Patterns | Refactoring

 Thursday, October 23, 2008

Yesterday, I was involved two very separate yet very related conversations. One was via twitter with Colin Jack and Jimmy Bogard (which I was only a partial contributor to - mostly just reading their conversation) and another after work with a coworker. The short version of both conversations can be boiled down to encapsulation of logic surrounding collections that are held by entities. Rather than rehash all of the conversations, I wanted to specifically address a violation of encapsulation that I've seen many times when dealing with collections and business rules.

Let's look at a small example where we have a medical system that deals with Patients that are having Consultations with doctors. There is a need to keep track of the historic consultations and also the current consultation, if any. For simplicity we'll say that the current consultation is identified as being the most recent, based on a starting date, and that any previous consultation must have an ending date. A very simplistic implementation of an object model to represent patients and consultations may look something like this:

public class Patient
{
  private IList<Consultation> _consultations = new List<Consultation>();
 
  public IList<Consultation> Consultations { get { return _consultations; } }
 
  public Consultation CurrentConsultation { get; set; }
}
 
public class Consultation
{
  public DateTime StartingDate { get; set; }
  public DateTime EndingDate { get; set; }
}

Then, when the time comes to add a new consultation to the patient, making it the current one and closing a previous consultation, code may get called from somewhere in the application (like a code behind of a form, or if you're lucky, in the Presenter or Controller of an MVP/C setup), like this:

Consultation consultation = new Consultation{ StartingDate = DateTime.Now };
 
patient.Consultations.Add(consultation);
 
if (patient.CurrentConsultation != null)
  patient.CurrentConsultation.EndingDate = DateTime.Now;
 
patient.CurrentConsultation = consultation;

From a purely technical standpoint, there is nothing wrong with this code. It implements the business rule as defined. However, this code misses out on some great opportunities to encapsulate the rules we have into a process that can be called from anywhere that the system needs it - whether or not the code is in the specific presenter / controller that creates a new consultation or not. The very same code that comprises this implementation could easily be placed in the Patient object, abstracting the rules and process of creating a new consultation into a simple, single method call.

Before I show how I would approach that solution, though, there is one other implementation that I've seen recently that not only breaks encapsulation, but has to compensate for the lack of rules enforcement with logic in the wrong place. Instead of storing the current consultation as a set value, the CurrentConsultation property may have some logic in it to dynamically determine which consultation is the current one.

public class Patient
{
  private IList<Consultation> _consultations = new List<Consultation>();
 
  public IList<Consultation> Consultations { get { return _consultations; } }
 
  public Consultation CurrentConsultation 
  {
      get 
      {
          Consultation currentConsultation;
          DateTime mostRecent = DateTime.MinValue;
          foreach(Consultation consultation in _consultations)
          {
              if (consultation.StartingDate > mostRecent)
              {
                  mostRecent = consultation.StartingDate;
                  if (consultation.EndingDate == DateTime.MinValue)
                  {
                      currentConsultation = consultation;
                  }
              }
          }
      }
  }
}

This type of code is a huge encapsulation violation smell. Since our Patient object has no enforcement of the consultations that it holds, there is no way for us to really know which consultation is the current one. Because of this, the retrieval of the current consultation has to process the entire consultation collection and try to find the most recent consultation that has no ending date.

On top of the encapsulation issue, we have lost a great deal of performance. We now have to loop through the list every time we need the current consultation. If the list is small, this might not be such a bad problem, but as the list grows and as this code is used more and more, the performance problem may have a serious impact on the system.

Fortunately, the solution to the encapsulation violation, the enforcement of the business rules and the performance problem can all be wrapped up in to some very simple code. The first thing we want to do is prevent the ad-hoc addition of consultations to the patient. We still need to access the list of consultations, but we don't really have a need to modify it outside of the patient class itself. This can be done with a one-line code change to the Patient class's Consultations property:

public class Patient
{
  private IList<Consultation> _consultations = new List<Consultation>();
 
  public IEnumerable<Consultation> Consultations { get { return _consultations as IEnumerable; } }
 
  //ignoring other implementation details for the sake of illustrating the IEnumerable change
}

Now that we have prevented the ability to do ad-hoc consultation additions, we need a way to actually add consultations. While we are doing this, we also want to enforce the business rules of the current consultation as described earlier. This is where we are going to take much of the original code that we found in the presenter / controller and place it into the patient class directly.

public class Patient
{
  private IList<Consultation> _consultations = new List<Consultation>();
 
  public IEnumerable<Consultation> Consultations { get { return _consultations as IEnumerable; } }
 
  public Consultation CurrentConsultation { get; private set; }
 
  public void StartConsultation()
  {
      Consultation newConsultation = new Consultation{ StartingDate = DateTime.Now };
 
      if (CurrentConsultation != null)
          CurrentConsultation.EndingDate = DateTime.Now;
 
      CurrentConsultation = newConsultation;
 
      Consultations.Add(newConsultation);
  }
}

In the end, this code shows a better encapsulation of the business rules and logic that surrounds the need to maintain a list of consultations and a current consultation. With this code in place, we could simplify the presenter / controller that we talked about initially. Rather than being forced to know all of that logic in the presenter, we can make one simple method call:

 
 patient.StartConsultation();
 

With this one simple call, we have a guaranteed execution of the business rules that we need. This will allow us to recreate the ability to add a new consultation at any point in the application that we need, not just in the original presenter / controller that we were working with.

Side Note:

Part of the conversation via twitter revolved around where this type of logic should be encapsulated. From what I gathered, Colin tends to place this logic in custom collection objects, which would allow him to call patient.Consultations.Add() and still encapsulate the same business rules into that method. Like everything else in software development, there are multiple ways to solve the same problem. What does your specific situation, project, team, and business context need? Whatever your implementation needs are, though, we need to keep this type of logic and business rules enforcement well encapsulated in our systems.



Cross Posted From LostTechies.com
Thursday, October 23, 2008 9:49:09 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET | Analysis and Design | Design Patterns | Domain Driven Design | Model-View-Presenter | Principles and Patterns | Refactoring

 Monday, October 20, 2008

A coworker recently asked if we should always abstract every object into an interface in order to fulfill the Dependency Inversion Principle (DIP). The question stunned me at first, honestly. I knew in my head that this was a bad idea - abstracting into interfaces for the sake of abstraction leads down the path of needless complexity. However, I wasn't able to clearly answer his question with specific examples of when you would not want to do this, at the time. I've been thinking about this for a few days now and I think I have a good, albeit very long winded, answer.

Before the question is answered, though, we need to step back and look at what DIP is all about. I've previously shown how to implement DIP and talked about why it's beneficial, so I won't be repeating that here. Rather, I want to talk about the language that describes DIP and what it really means.

Robert Martin's original definition of DIP is this:

A. High level modules should not depend upon low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.

The word 'abstraction' is used three times in the definition for DIP. So, in order to understand DIP, we have to first understand some of the basics of Abstraction.

Some Background On Abstraction

From Wikipedia (emphasis mine):

"In computer science, abstraction is a mechanism and practice to reduce and factor out details so that one can focus on a few concepts at a time"

I can't say it any better than this.

Abstraction can very directly lead to a system that is more understandable by helping us ignore the detail and implementation specifics, allowing us to focus on something at a higher level. This reduction in cognitive load can benefit someone that is reading the code by not forcing them to know the detail immediately. Additionally, abstraction is a form of encapsulation or information hiding, which again helps us to reduce cognitive load and produce better systems. From Wikipedia's entry on Information Hiding:

"In computer science, the principle of information hiding is the hiding of design decisions in a computer program that are most likely to change, thus protecting other parts of the program from change if the design decision is changed."

At the heart of abstraction and information hiding, we find the ability to change the system. The ability to change is an absolute requirement in software development and produces good design that is easier to work with, modify, and put back together as needed. The inability to change is directly called "bad design" by Robert Martin, in the DIP article.

Applying Abstraction And Encapsulation To DIP

So how does our knowledge of abstraction and information hiding play into DIP?

First and foremost, DIP never states that we should depend on explicit interfaces. Yes, in C# we have an explicit Interface as a form of abstraction. It is a separation of the implementation detail from the publicly available methods, properties, etc, of a class. Some languages, such as C++, don't have an explicit construct for interfaces, though. From Robert Martin's original DIP article, again:

"In C++ however, there is no separation between interface and implementation. Rather, in C++, the separation is between the definition of the class and the definition of its member functions."

A String As An Abstraction

Abstraction does always mean explicit interface constructs, as evidenced in C++. Nor does it always mean an abstract base class, which we also have available in .NET. In fact, languages such as Ruby don't really need either of these constructs. The duck-type nature of Ruby allows an implementation to be replaced at any point, without any special constructs. In .NET, though, there are a number of abstraction forms that we can rely on, explicitly. We have the obvious interfaces and base classes (abstract or not) - but we also have constructs like delegates and lambda expressions, and even the simple types that are built into the base class library.

Let's look at a simple string to illustrate abstraction. As I said in my SOLID presentation at ADNUG, we can invert our dependency on database connection information.  Rather than putting a connection string directly into our code that calls the database, we can use the string as our dependency and our abstraction. All we need to do is follow the basic DIP principle and provide the string as a parameter to the class that calls the database. We certainly don't need (or want, for that matter) to introduce a new interface or base class at this point. Our abstraction is simple enough to use a common type found in the .NET framework.

Other Forms Of Abstraction

Even if we are talking about an object, who says that the interface we are depending on has to be an explicit interface construct or base class? When I write a Domain Service that uses an Entity from my Domain, I don't create an explicit interface for that Entity. Rather, I use the Entity's inherent interface - it's public methods, properties, etc.

I also use delegates on a regular basis. By specifying my abstraction as a delegate, I can further decouple the depending object from the dependant code that it needs to call. I'd be willing to bet you have used delegates as abstractions as well. Have you ever created an event handler for something like a button click? There's a delegate's abstraction at work.

Abstract Judgement

The point is, there is not always a need to introduce an explicit interface or base class when inverting our dependencies. We still need to apply dependency inversion and provide our implementation as a constructor parameter (or setter, though I don't like setter injection). But, that dependency doesn't have to be anything more than the interface inherent to the object, or a simple type found in .NET.

You do have to be careful when making the call to not use an explicit abstraction with DIP, though. You can quickly turn your system into a ball of mud if you rely on a concrete class that is not intention revealing or well encapsulated to begin with. At the same time, too many abstractions can lead to needless complexity and make it very difficult to see the big picture of a system. Too few abstractions, though, will certainly lead to a rigid, immobile design that is hard to change. All of these problems are equally vicious - and I've been bitten by all of them in recent months.  It takes good judgement calls to determine when you do and do not need an explicit abstraction for a dependency. Unfortunately, good judgement comes from experience and experience comes from bad judgement. Don't be afraid to make bad decisions - make a decision, just be sure you can reverse that decision as easily as possible.

Monday, October 20, 2008 5:04:54 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET | Agile | Analysis and Design | Domain Driven Design | Lambda Expressions | Philosophy of Software | Principles and Patterns | Refactoring

 Wednesday, October 15, 2008

Let's say I have a small hierarchy of object: Faults and Parts. A Fault can contain many parts, and a part has no meaning without being associated to a Fault. To ensure that I have no Parts without a parent Fault, I have this basic code in place:

public class Part
{
    private Part()
    {
    }
 
    public string Description { get; set; }
 
}
 
public class Fault
{
    private IList<Part> _parts = new List<Part>();
 
    public IList<Part> Parts { get { return _parts; } }
    
    public Part CreatePart()
    {
        Part part = new Part;
        _parts.Add(part);
        return part;
    }
}

This ensures that I never have a Part in an "invalid" state - without an owning parent.

I also have a business rule that say that I'm not allowed to have a Part without a description. My typical implementation of this business rule has been in the UI layer - my Presenter would have the logic to require a user to enter a description when creating adding a part to a fault.

public class PartCreationPresenter
{
 
    Part _part;
 
    public PartCreationPresenter(Part part)
    {
        _part = part;
    }
 
    public DescriptionProvided(string desc)
    {
        if (string.IsNullOrEmpty(desc))
        {
            view.ShowDescriptionRequiredMessage();
        }
        else
        {
            _part.Description = desc;
        }
    }
 
}

Here's the question:

Should this "require a description" logic be in the UI layer (Presenter) the way I have it, or should I put it in the Part object and have an IsValid flag of some sort on that object?

I don't like having this coded in the presenter only. It makes the business rule very easy to break - create a part from anywhere else, and you can ignore this rule. But I'm not sure I like it in the Part object, because it would make the presenter difficult to code. How would I execute the specific view.ShowDescriptionRequiredMessage() method if the rule is coded in the Part?

Any opinions, suggestions, articles, etc. are very welcome. I'm very interested in hearing how other people are handling this situation.

Wednesday, October 15, 2008 10:54:12 AM (Central Standard Time, UTC-06:00)  #    Comments [2]. Trackback 
Tags: .NET | Analysis and Design | Design Patterns | Domain Driven Design | Model-View-Presenter

 Tuesday, October 14, 2008

I had a lot of fun giving my SOLID Principles presentation at the Austin .NET User Group last night. It was a pleasure and an honor to be able to give back to the community that has supported me for so many years.

I'd like to thank everyone that came out to see the presentation, for being such a great audience. There were a lot of great questions and comments and good discussion. I sincerely hope that I've inspired at least a few people to continue digging into the SOLID principles.

As promised, I've posted my slides and the example code for download.

Additional resources for SOLID:

For the questions on legacy code from last night:

If anyone has any questions about the SOLID principles, would like more information, etc, please feel free to contact me via the contact link on my blog(s) or via my email address listed at the end of the slides.

Tuesday, October 14, 2008 10:55:57 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET | Community | Principles and Patterns

 Thursday, October 09, 2008

A coworker just asked me this question - what's the point of delegates in .NET? My answer was very short and one that he had not found online: to delay execution of a method.

Consider this: if you pass a Method2 as a parameter to Method1, Method2 is evaluated immediately and the result is passed into Method1.

public class SomeObject
{
    public void Method1(int someValue)
    {
        //... code here
    }
}
 
...
 
someObject.Method1(anotherObject.Method2());

Additionally, Method2 must have a return value (not void) so that the value returned from Method2 can be passed as the parameter of Method1.

With a delegate, though, we get method pointers that can be used to delay the execution of the method in question until it's needed (if at all). We can also get rid of the requirement for a return value and we can pass values that were created by the host method, into the delegate method.

public class SomeObject
{
    public void Method1(Action<int> someAction)
    {
        //.. do some stuff here
        int aValue = GetTheValueFromSomeWhere();
        someAction(aValue);
        //... do some more here
    }
}
 
public class AnotherObject
{
    public void Method2(int aValue)
    {
        //do something that is dependent on aValue, here.
        int i = aValue + 1; // or anything else that needs aValue.
    }
}

FYI - Action (void return; with many parameterized variations) is a delegate that is build into .NET 3.5, along with Func<T> (return value of type T; with many parameterized variations). These are the two most common delegates that I use in my code.

Most .NET developers have used delegates without realizing it, too. The event system in .NET is nothing more than a multi-cast delegate - a delegate that points to more than one method - with a special signature and syntax (depending on the language being used).

There's a lot of good use for delegates. And like any other tools, there's a lot of bad uses. Take the time to learn what they are, how they work, and where they can be beneficial.

Thursday, October 09, 2008 4:05:00 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET

FYI - I'll be giving my S.O.L.I.D. Software Principles presentation at the Austin .NET User Group on Monday the 13th. This is the same presentation that I gave at Pablo's Day(s) of TDD last weekend, except I'll have the missing code in place and the slide errors fixed.

Here's the abstract that was posted via the ADNUG mailing list:

S.O.L.I.D. Software Development: Achieving Object Oriented Principles, One Step At A Time 

Almost every professional software developer understands the academic definitions of Coupling, Cohesion, and Encapsulation. However, many of us do not understand how to actually achieve Low Coupling, High Cohesion, and strong Encapsulation, as prescribed. Fortunately, there are a set of stepping stones that we can use to reach these end goals, giving us a clear cut path to software that is easier to read, easier to understand, and easier to change. This presentation will define not only the three object oriented goals, but also the five S.O.L.I.D. principle that lead us there, while walking through a sample application.

At some point this week or next, I will have my slides and code posted for people to download. (I know I promised this at PDoTDD. I got busy. Sorry). And as usual, there will likely be a group of people heading to Rudy's after the meeting, for extended discussions and snappy banter.

Thursday, October 09, 2008 9:55:56 AM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET | Analysis and Design | Community | Principles and Patterns

 Tuesday, October 07, 2008

A few months ago, I posted some thoughts and questions on the proper use of Inversion of Control (IoC) containers and the Dependency Inversion (DI) principle. Since then, I've had the opportunity to do some additional study and teaching of DI, and I've had that light bulb moment for the proper use of an IoC container. I haven't talked about it or tried to present the info to my team(s) yet, because I had not verified my thoughts were on the right track - until recently. I got to spend a few hours at the Dovetail office with Chad, Jeremy, Josh, etc, and had the pleasure of being able to pick their brains on some of the questions and thoughts that I've had around DI and IoC. In the end, Chad confirmed some of my current thoughts and helped me put into a metaphor that I find to be very useful in understanding what Dependency Inversion really is - a cloud objects that can be strung together into the necessary hierarchy, at runtime.

Consider a set of classes that need to be instantiated into the correct hierarchy so that we can get the functionality needed. It's really easy to have the highest level class - the one that we really want to call method on - instantiate the class for next level down, and have that class instantiate it's next level down, and so-on, like this:

image

This creates the necessary hierarchy, but breaks the core object oriented principle of loose coupling. We would not be able to use ThisClass without bringing ThatClass along with it, and we would not be able to use ThatClass without bringing AnotherClass along with it.

By introducing a better abstraction for each class and putting Dependency Inversion into play, we can break the spaghetti mess apart and introduce the ability to use any of these individual classes without requiring the specific implementation of the dependent class.

For starters, let's introduce an interface for ThisClass to depend on and an interface for ThatClass to depend on.

Adding Dependent Interfaces

Now that we have an interface that both of these classes can depend on, instead of the explicit implementation of the child object, we need to have the expected child object implement the interface in question. For example, we expect ThatClass to be used by ThisClass, so we will want ThatClass to implement the IDoSomething interface. By the same notion, we want AnotherClass to implement the IWhatever interface. This will allow us to provide AnotherClass as the dependency implementation for ThatClass. Our object model now looks like this:

Implementing Dependency Interfaces

What we have now is not just a set of classes that all depend on each other, but a "cloud" of objects with dependencies and interface implementations that will let us build the hierarchy we need, when we need it.

The Cloud Of Objects

The real beauty of this is that we no longer have to care about the implementation specifics of IDoSomething from ThisClass. ThisClass can focus entirely on doing it's duty and calling into IDoSomething when it needs to. And, by passing in the dependency as an abstraction, we're able to replace the dependency implementation at any time - runtime, unit test time, etc. This also makes our system much easier to learn and understand, and most importantly - easier to change.

Now that we have our cloud of implementations and abstractions in place, we will need to reconstruct the hierarchy that we want so we can call into ThisClass and have it perform it's operations. Here's where Dependency Inversion meets up with Inversion of Control.

  • To create ThisClass, we need an implementation of IDoSomething
  • ThatClass implements IDoSomething, so we'll instantiate it before ThisClass
  • ThatClass needs an instance of IWhatever
  • AnotherClass implements IWhatever, so we'll instantiate it before ThatClass
  • Once we have AnotherClass instantiated, we can pass it into ThatClass's constructor
  • Once we have ThatClass instantiated, we can pass it into ThisClass's constructor

We end up with a hierarchy of objects that is instantiated in reverse order, like this:

Reconstructing The Hierarchy Of Depdencies

We have now successfully inverted our system's construction - each implementation detail is created and passed into the the object that depends on it, re-creating our hierarchy from the bottom up. In the end, we have an instance of ThisClass that we can call into, with the same basic hierarchy of classes that we started with. The real difference is that now we can change this hierarchy at any time without worrying about breaking the functionality of the system.

Once we have our Dependency Inversion and Inversion of Control in place, we can start utilizing the existing IoC frameworks to automatically create our hierarchy of objects based on the advertised dependencies (an advertised dependency is a dependency that is specified as a constructor parameter of a class). Tools like StructureMap, Spring.net, Windsor, Ninject, and others, all provide automagic ways of creating each dependency of the object that is requested, all the way up/down the hierarchy. Utilizing one of these IoC containers can greatly simplify our code base and eliminate the many object instantiations that would start to liter our code. As I said in my previous post, I know all about what not to do with IoC containers. Good IoC usage, though, is another subject for another post.

Tuesday, October 07, 2008 9:18:31 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: .NET | Analysis and Design | Design Patterns | Principles and Patterns | Refactoring | Unit Testing

It's official - I'm now a member of Los Techies. I will continue to post here, at DerickBailey.com, and will be cross-posting over at Los Techies once I figure out how to do that.

Thanks to Joe, Chad, and everyone else in the Los Techies crew, for the vote of confidence in adding me!

Tuesday, October 07, 2008 2:09:23 PM (Central Standard Time, UTC-06:00)  #    Comments [0]. Trackback 
Tags: Community

 Monday, September 29, 2008

At some point, you will need to put a timer into your C# code. Hopefully you're doing Test Driven Development, or at least unit testing, to cover your need for a timer with a unit test. If you are - I'm betting you ran into some really ugly problems like tests that would not pass without having 'Thread.Sleep(1000)' calls in them. Worse yet - last week, I put a 3 second timer into a class that was being unit tested. This one mistake cause my CruiseControl build to go from 2 minutes, to timing out at 90 minutes because NUnit was keeping the app domain alive while the timer was alive, so it never closed the test run. Oops.

To fix this problem, we decided we needed to eliminate the use of an actual timer and use an abstraction that could be mocked/controlled in our unit tests. Unfortunately, the .NET Framework does not have an actual abstraction for a timer. So, if you need to use a timer in your code - and at some point in time, you will - you'll want to create a very simple ITimer interface that would let you control when the timer elapses and fires its registered action.

Here's the core of the abstraction that we came up with, initially.

public interface ITimer
{
    void Start(Action timerAction);
}

With such a simple interface in place, we can now mock it out in our unit tests (I like Rhino Mocks) and set up an expectation on the Start method to capture the timerAction parameter, then simulate the timer elapsing by calling the timer action from our unit test. Here's an example test and 'system under test' to illustrate how we use this interface.

[Test]
public void DemonstratingHowToUnitTestATimerElapsing()
{
    Action timerElaspedAction;
    ITimer timer = MockRepository.GenerateMock<ITimer>();
    timer.Expect(t => t.Start(null)).IgnoreArguments().Callback(
    delegate(Action timerAction)
    {
        timerElapsedAction = timerAction;
        return true;
    });
 
    MySystemUnderTest sut = new MySystemUnderTest();
    sut.StartMonitoringStuff(timer);
 
    //here's where we simulate the timer elapsing
    timerElapsedAction();
 
    Assert.IsTrue(sut.TheTimerActionWasCalled);
}
 
public class MySystemUnderTest()
{
    public bool TheTimerActionWasCalled { get; set; }
 
    public MySystemUnderTest()
    {
        TheTimerActionWasCalled = false;
    }
 
    public StartMonitoringStuff(ITimer timer)
    {
        timer.Start(() => TheTimerActionWasCalled = true);
    }
}
 

There is a bit more detail to the actual ITimer interface, and the implementation, though. We ran into issues where we needed to stop the timer, prevent it from firing after we close the SUT, etc. So, all said and done, here's the full ITimer interface and MyTimer implementation that we ended up with.

public interface ITimer
{
   void Start(Action action);
   void Stop();
}
 
public class MyTimer : ITimer, IDisposable
{
 
   private TimeSpan _timerInterval;
   private Timer _timer;
 
   private Action _timerAction;
 
   private bool IsRunning { get; set; }
 
   public MyTimer(TimeSpan timerInterval)
   {
       _timerInterval = timerInterval;
   }
 
   public void Dispose()
   {
       StopTimer();
   }
 
   public void Start(Action action)
   {
       _timerAction = action;
       IsRunning = true;
       StartTimer();
   }
 
   public void Stop()
   {
       IsRunning = false;
       StopTimer();
   }
 
   private void StartTimer()
   {
       _timer = new Timer(o => Timer_Execute(), null, 0, Convert.ToInt32(_timerInterval.TotalMilliseconds));
   }
 
   private void StopTimer()
   {
       if (_timer != null)
       {
           _timer.Change(Timeout.Infinite, Timeout.Infinite);
           _timer.Dispose();
           _timer = null;
       }
   }
 
   private void Timer_Execute()
   {
       try
       {
           StopTimer();
           _timerAction();
       }
       finally
       {
           if (IsRunning)
               StartTimer();
       }
   }
 
}

This has worked out very well for us, so far. It lets us put a timer in place when we need one, but not worry about thread racing issues, long running tests, etc.

Monday, September 29, 2008 7:38:33 PM (Central Standard Time, UTC-06:00)  #    Comments [2]. Trackback 
Tags: .NET | Lambda Expressions | NAnt | Rhino Mocks | Test Driven Development | Unit Testing

Navigation
About Me
View Derick Bailey's profile on LinkedIn

Send mail to the author(s) Contact Me
Archive
<October 2008>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Derick Bailey
Sign In
Statistics
Total Posts: 115
This Year: 0
This Month: 0
This Week: 0
Comments: 44
Themes
Pick a theme:
All Content © 2010, Derick Bailey
DasBlog theme 'Business' created by Christoph De Baene (delarou)