Showing posts with label Principles. Show all posts
Showing posts with label Principles. Show all posts

Wednesday, January 15, 2014

Interface level validations of DataObjects

Purpose

I was recently working on a project where I wanted to create the most granular interfaces possible and then group them into usable objects. My intent was to pass these objects around to shared utilities and services that would focus on the interfaces and thus be reusable by intent instead of specific implementation. For example, we would create an interface each for phone number, email and street address. These interfaces could be used on a customer, vendor, or employee object to ensure a standard implementation of the fields. Then, we could build our communications services to work off the interfaces for communication types and thus be generic to the entity being contacted. By doing this, I would be able to build singularly focused services that dealt with small tasks on data objects with a disregard for their specific implementation beyond the interface.

Validation

Being a big fan of data contracts with ability to run self-aware validations(e.g. validations that can only consider the scope of the contract itself without any relationships), I found myself needing a way to have all objects validate based on the requirements of the smaller interfaces, within the CRUD services of the manifested object. I also wanted to ensure the ability to dynamically add validation routines and have them picked up by the calling services without having to couple them together.

Solution

By creating a custom attribute and applying it to methods in the interface, I would be able to reflect through the methods of any object and trigger it to self validate using any and all methods that were added to the object from the implemented interfaces. Next, we simply call a data contract extension method that to invoke all validations. Here are the examples.
Custom Method Atribute

[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public class InterfaceValidation : Attribute
{
    //...
}
Data Contract Extension

public static class DataContractExtensions
{
    public static T CallInterfaceValidations<T>(this T obj)
    {
        var methods = obj.GetType().GetMethods();
        object[] parameters = null;
        foreach (var method in methods)
        {
            var attributes = method.GetCustomAttributes(typeof(InterfaceValidation), true);
            if (attributes != null && attributes.Length > 0)
            {
                try
                {
                    method.Invoke(obj, parameters);
                }
                catch (Exception)
                {

                    throw;
                }

            }
        }
        return obj;
    }
}
Assign the attribute to a method

[InterfaceValidation]
void ValidateSomething();




Friday, December 27, 2013

Inversion of Control Pattern

Dependency Inversion Principle

The DIP states that high level classes should not depend on low level classes.  Both should depend on abstractions.  Details should depend on abstractions.  Abstractions should not depend on details.  The DIP is about reversing the direction of dependencies from higher level components to lower level components such that lower level components are dependent upon only the interfaces owned by the higher level components.  This is a method for moving to a more loosely coupled architecture.  Basically, you have to depend on a standard interface used by objects and not depend on their details.  This one might be best illustrated by example. 

In the following example, the BadCar class is tightly coupled to the actual implementation of the BadMotor function.  This means that these two objects are married, and changes to one directly impact the other.

public class BadMotor
{
    public Boolean Start()
    {
        Console.Write("Starting");
        return true;
    }
}
 
//tightly coupled to details.
public class BadCar
{
    public BadMotor Motor {get;set;}
 
    public Boolean Start(BadMotor badMotor)
    {
        Motor = badMotor;
        return Motor.Start();
    }
}
 
 
While this does function, it creates a dependency relationship between two objects at their implementation level.   This creates hardships for maintenance and scalability long term.   The proper way to build this relationship would be to invert dependencies onto interfaces to ensure no object has knowledge or visibility into implementation of any other object. Consider the following examples:
public interface IEngine
{
    bool Start();
}
 
public interface IGreenEngine : IEngine
{
    bool IsCharged ();
}
 
public class FourCylEngine : IEngine
{
    public bool Start()
    {
        Console.WriteLine("4Cyl Starting");
        return true;
    }
}
 
public class V8Engine : IEngine
{
    public bool Start()
    {
        Console.WriteLine("V8 Starting");
        return true;
    }
}
 
public class HybridEngine : IGreenEngine
{
    public bool Start()
    {
        if (IsCharged())
            Console.WriteLine("Hybrid Starting");
        return true;
    }
    public bool  IsCharged()
    {
        Console.WriteLine("Hybrid is charged");
        return true;
    }
}
 
public class Car
{
    public Car(IEngine engine)
    {
        Engine = engine;
    }
    public IEngine Engine{get ; set ; }
    public Boolean Start()
    {
            
        return Engine.Start();
    }
}
 
I built this interface dependency and inheritance to ensure that objects are loosely coupled and only share an interface.   This allows for actual base implementations to come and go and even be recognized dynamically without causing lower level objects to update their implementation.   Here is an example of hot swapping and scaling with the previously defined objects and interfaces.
class Program
{
      
    static void Main(string[] args)
    {
        //  Cars are only dependant upon an Engine interface
        Car BigThing = new Car(new V8Engine());
        BigThing.Start();
        //  Cars are only dependant upon an Engine interface
        Car SmallThing = new Car(new FourCylEngine());
        SmallThing.Start();
        // Since we have an interface dependency, it is easy to hot swap.
        BigThing.Engine = new HybridEngine();
        BigThing.Start();
    }
}

The output is as follows:


As you can see, this allows for maintainability and long-term scalability by ensuring that the objects stay out of each other's business. By adhering to the spirit of this principle as well as the previous SOLID principles, you can keep your code base healthy and easy to maintain when the requirement changes come.

Wednesday, May 15, 2013

Automated Testing

Automated testing as a strategy

Automated testing is a great and powerful tool for ensuring consistent code coverage, performing fast regression tests, validating builds and locating potential code problems.  The introduction of automated testing into your processes should give you a noted increase in productivity and QA throughput. While it is true that the automated testing will improve your coverage and productivity, it is not the answer to every 'QA bottleneck' issue in history.  Beware of jumping to conclusions about what automated testing will bring to the table and instead focus on where it gains the most value.  It will never replace human testing in its entirety.  It simply will not replace manual testing in aspects such as product exploration and environmentally varied user story testing.

Automated tests will remove much of the burden from a human resource by testing a single action or logical group of actions repeatedly.  That is the great gift of automated testing, but it cannot entirely take the place of a human with platform knowledge exploring the product for cause and effect testing. It is important to focus your testing investments where they will have the most return.

Mike Cohn created a test automation pyramid indicating a good break down of test investments.  I have taken that and applied it to the platforms we are dealing with daily.  This pyramid illustrates a healthy distribution of test investment for complete platform coverage and explains how the investment in tests should focus at the unit level and then reduce up through the application layers.



Unit Tests

Unit tests should be your highest investment in code coverage.  These tests are created by the developers as they write the corresponding code. In a SOA world, every line of code in a service should have a corresponding unit test.  This includes all methods, extensions, data contract validations, CRUD operations and authentication routines.  These should have a test created as part of the development process.  Even when a modification is made to existing service, the modification must have corresponding tests to prove it is functioning as requested.  By its nature, a unit test will inherently give your platform total code coverage at a very base level.  It is important that all unit tests deal with every possible code path within the method being tested.  Cyclomatic complexity limitation is a standard specific metric that should be enforced with scripts, tools or code reviews, but will keep your unit tests, as well as your methods, clear, concise and focused.  For the sake of focus, I am avoiding the CC soapbox for today. This flavor of automated testing gives you the most absolute code coverage and is the base for automated testing.

Integration Tests

Integration testing is created by QA automation employees and is meant to validate functionality of entire user stories.  This is where other considerations such as performance should be measured. Integration tests should be SOA tests, meaning that the integration test plays the role of the presentation layer in executing a chain of tasks comprising user stories. These tests are constructed to validate and measure larger functional items that consist of many small service calls. A good example of an integration test is a long story consisting of customer creation, order creation, payment creation, editing of account credits and debits and comparing the end result against known values for outcome, performance and A/R.  The integration test provides regression testing at the user story level and needs to be done to all USL and SDK-API methods, as they are the outer most points in the SOA.  This type of automated testing offers the most user story coverage and should comprise the primary basis for validating the quality and functionality of your platform.

UI Tests

The UI test is the process of ensuring a UI meets specifications. UI tests are created by QA automation employees and are simply a robotic replacement for a human moving through the platform and executing the elements within a UI.  UI testing is a valid and valuable platform for product stability, but is ultimately a less indicative test of total platform quality than the areas before it.

Human Testing

Human testing should be approached as primarily an exploratory testing methodology.  In this environment, a person familiar with the platform spends the time varying individual environment variables and testing the functionality of the platform.  This is the layer at which testing no longer reflects a series of repeatable actions and begins to reflect an individual creatively trying to find flaws in a system. This is a valuable test concerning ensuring that a platform will be stable when not being used correctly or encountering anomalies in the standard environment. 
If approached with the proper expectations and focus, automated testing can be the answer to many aspects of QA that seem slow and redundant.  If we ensure the proper level of investment at each area of testing, the platform coverage can be complete and result in a much faster and more thorough acceptance process.

Thursday, April 18, 2013

Extension Methods

I recently saw an email where a development manager was reminding his team of the value of extension methods.  This is a great method for adding base class type functionality to objects without introducing dependencies and utility classes for simple functions.

Extension methods are an easy way  to "add" functionality to existing types without having to create derived types, recompile, or otherwise modify the original type. Extension methods are a static method, but they are called as if they were methods on the target type. Using C#, there is no apparent difference between calling an extension method and the methods that are actually part of the defined type.

Here is an example extension method.  This method will extend the object string to break apart camel cased names and return a human readable name.  This can be very useful for populating drop down lists with all values of an Enumeration and other such activities.  First, we create the static method as follows.

public static string SplitCamelCase(this String input)
{
    return Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled).Trim();
}
This simply create a method (SplitCamelCase) and adds it to the methods available to any String variable in namepace scope with this class.

Then, this method can be called in the same format as any other method on the type String.


static void Main(string[] args)
{
    String testValue = "ThisIsACamelCasedSentence";
    Console.WriteLine(testValue.SplitCamelCase());
} 

These methods are quite simple to create and yet are a very powerful replacement for utility classes.  They can be used on native types as well as complex types.

Thursday, April 4, 2013

Inversion of Control (IoC) Pattern

I have been involved in many architectural discussion lately, where groups of people have been throwing around ideas on the correct way to build systems.  I am always coming from a position of loosely coupling and making sure that all aspects of your system are interchangeable and have the ability to be dynamically changed or replaced without system wide impact.  One topic that I find myself mentioning over and over again is the pattern known as Inversion of Control. Inversion of control (IoC) is a OOP technique by which  object coupling is bound at run time by an another object that is typically not known at compile time using static analysis.  The basic idea of this pattern is separate the creation of an object from the class which is trying to consume it.

The problem

As with every design pattern, the reasoning behind IoC is to avoid the possibility of design related problems.  For example, let's create an Appointment class which contains a Person class object. The biggest issue with the code below is tight the coupling between classes. In other words the Appointment class depends on the Person object. This main seem innocuous enough at a glance.  But, the byproduct of this design is that  if for any reason Person class changes, it will lead to a compile of the Appointment class. Then, in our world any object compilation leads to regression testing of the recompiled object, even though there was not an actual change. 
public class Person
{
}

public class Appointment
{
    private Person person;

    public Appointment()
    {
        person = new Person();
    }
}
The biggest problem with the sample code is that the appointment class controls the creation of Person object.  The patient class is directly referenced in the Appointment class which leads to tight coupling between these two objects.The Appointment class is aware of the Person class type. So if we add new Person types (like patient, sales person, employee, or pet), it will lead to changes in the Appointment class also as Appointment class is exposed to the actual Person implementation.  This also means that the creation of the Appointment class is dependent upon the successful creation of the Patient object within it's constructor.

The solution

If we are able to shift this task / control of object creation from the Appointment class to some other entity we have solved our problem. This means we are able to invert the control to a third party object and thus have found the solution. Some people call the IoC pattern the 'Hollywood' pattern because the simplest explanation of it's purpose is summed up the in phrase "Don't call us, we'll call you." This is a good summary of the idea of this pattern. There are many ways to accommodate this pattern with varying degrees of overhead. In my opinion, the simplest implementation of an IoC Container. IoC containers are used to simplify the provision of a dependant class's dependencies. In the most basic form, an IoC container is an implementation of the service locator design pattern that permits pre-instantiated objects to be registered with the container and later extracted. To substitute a new class and modify the operation of an entire solution, only the initial registration of the type need be changed.

IoC Container

Some IoC containers allow you to register types, rather than objects, and instantiate the type when requested, possibly using parameters. Others allow the registrations to be deserialised from an XML file, which could be modified in a text editor. In this article we will create a basic IoC container that does not include these additional features. This will demonstrate the use of IoC containers with the simplest possible code. You may decide to enhance the code to add extra features for your own use. However, you should also consider obtaining one of the many alternative IoC container solutions that are currently available. Following is the code to create a very a basic IoC container.
public static class IoC
{
    static Dictionary<Type, object> _registeredTypes = new Dictionary<Type, object>();

    public static void Register<T>(T toRegister)
    {
        _registeredTypes.Add(typeof(T), toRegister);
    }

    public static T Resolve<T>()
    {
        return (T)_registeredTypes[typeof(T)];
    }
}

Using the IoC Container

To illustrate the usage of the IoC container we first need to create an interface and a class that implements it. We will later register an instance of the class for the interface's type. The code for a simple interface and class that is used to grab a value are as follows:
public interface IPerson
{
    void SayYourName(string name);
}


public class Person : IPerson
{
    public void SayYourName(string name)
    {
        Console.WriteLine(name);
    }
}
We can now register the interface's type and provide a new Person object, which will be returned whenever the type is resolved. You would usually do this when your application is first started. In this example we will only register one type. In a real solution you can register as many types as are required for the operation of your software.
static void Main(string[] args)
{
    IoC.Register<IPerson>(new Person());
    IPerson person = IoC.Resolve<IPerson>();
    person.SayYourName("Jim Garrett");  
}
Once registered, any code that has access to the IoC class can resolve the type. In the sample the first line requests the object from the IoC container that implements IPerson. This returns the previous registered Person object. The object is then used to output a message to the console.

Tuesday, March 12, 2013

The argument for coding standards



Creating and enforcing coding standards, or coding style guidelines, is one method by which software companies can ensure that source code written by a software developer is easily understood, while being maintained by any other software developer in their employ.  Smashing Magazine contributor Nicholas C. Zakas penned an article titled, “Why Coding Style Matters”, illustrating the value realized by creating and adhering to coding standards.  He states that standards ensure individual members of a development team are able to tailor the visual appearance of their source code while still allowing their individual talents to flourish.  Standardized coding style also ensures better communication between team members by allowing the product of work to act as a form of documentation for the creators to leave clues for themselves and for others who come after.  Potential programming errors are more easily identified when a group of programmers adheres to a coding standard since any code that does not comply becomes more visible and draws scrutiny of other developers.  Standardizing the code comment, which is a way for developers to create non-executing code strictly designed for inter-developer communication, is a good way to ensure other engineers are able to understand why code was written in this specific way to accomplish the known task.

Zakas begins the article by discussing his own introduction to coding standards as a student in college.  One of his professors considered the style with which code was written equally as important as the execution of the code.  His definition of coding style is insightful as it illustrates that the standard can be as generalized or granular as the creator desires.  All individual developers inherently have a coding style, whether formalized and forced or inadvertently formed in seclusion over time. The biggest challenge with a standardized style to a creative group, he states, is the undeniably personal nature of any style.  Mr. Zakas created a memorable simile regarding individual musicians in a band.  While all of the musicians have a talent on their instruments, unless they are orchestrated in some fashion beyond their individual creative style, the music they produce will not likely be enjoyable to the listener.  The structure provided by band governance for items such as tempo, key, and lead timing, ensures a quality musical product without forcing the conformance of individual creativity.  That is exactly the marriage of the individual dynamic within a team structure that is required.  Prior to enforcing standards, you have to understand the challenges and resistance will be based on individual styles and creativity being 'standardized'.  It is vital to communicate that coding standards and style guides do not throttle creativity or individualism, they simply channel it into a team effort and ensure forward progress.

Communication is a natural and valuable byproduct of coding standards.  Most communication within a group of developers is resident within the source code itself.  The output of any developer’s daily work is a complete, exhaustive, and readable trail of every task he or she executed.  When one developer reads the source code created by another developer, the original developer’s view of the problem, strategy to correct it, and final solution are communicated to the second via the code itself. Once you reach this realization alone, it indicates the need for standardization.  The code communication is also useful for developers to leave clues for themselves in the future.  It is equally important for the author of the code to understand that he may need to maintain a creation of his own in the distant future.  Intellectual breadcrumbs and standardized formatting will ensure that old code and new code look the same to the maintaining programmer.

Coding standards bring potential software errors into view more easily.  As programmers become more acclimated to specific patterns, they will more naturally notice code that does not adhere.  This ultimately draws the attention of programmers and causes them to consider the segment of code more closely, as it is an anomaly.  Since the coding standard itself is designed to enable consistently stable source code, one must focus on which items to standardize with direct intent.  You will probably not find a coding style guide with too much detail, but can find them with too little detail.  The importance in your level of detail is based on the importance of ensuring items that are standardized are complete and targeted at specific items important to the individual team.  In other words, its not a good idea to standardize every aspect of development, just for the sake of doing it.  You should focus on standards as they align with your business need and allow the developers to leverage their creativity and talent within the style guide.

Monday, June 25, 2012

Dynamic Types Using C#


I ran across a scenario the other day for creating a function to perform similar work on similar classes without having to be tightly coupled to any concrete type.  I found a few viable options and will be doing some examples of each to work through the exercise completely.  The first I want to talk through is the use of the dynamic keyword.

In short, using dynamic tells the compiler to ignore types at compile time and instead determine dispatch based on the actual type at run time.  Static binding of types does the exact opposite and performs a dispatch based on the concrete type.  Since code always illustrates these academic discussions more clearly, I created a simple project.  I have two examples of dynamic typing built into this single example.  I created some classes to illustrate a few types that are completely unrelated to each other. I also created a single class that was an example of type inheritance.

public class Account
{
    public String Name { get; set; }
    public Double Balance { get; set; }
    public Int16 AccountType { get; set; }
    public Account()
    {
        Name = "Account";
        Balance = 100.00;
    }
}
 
public class Customer
{
    public String Name { get; set; }
    public Double Balance { get; set; }
    public String CustomerType { get; set; }
    public Customer()
    {
        Name = "Customer";
        Balance = 900.00;
    }
}
 
public class Employee
{
    public String Name { get; set; }
    public Double Balance { get; set; }
    public String Department { get; set; }
    public Employee()
    {
        Name = "Employee";
        Balance = 500.00;
    }
}
 
public class Payable : Account
{
    public Payable()
    {
        Name = "Payable";
        Balance = -100;
    }
}

As you can see, the classes are completely independent of each other, but they have similar members.  Using the dynamic keyword, we can create a function that deals with these types at runtime and interacts with expected members at that time.

static void WriteDynamicObject( dynamic thing)
{
    Console.WriteLine("Name: "+ thing.Name + ", Balance: " + thing.Balance.ToString());
}
 
As long as the types I pass to this function have publicly accessible members named Name and Balance, this code will work with a complete disregard for compilation of any known type.  Next, to illustrate using the dynamic keyword for instructing the runtime to resolve the type regardless of declaration, I created overloaded functions that take a concrete type at each level of inheritance.

static void WriteConcrete(Account thing)
{
    Console.WriteLine("I am an Account Thing");
}
static void WriteConcrete(Payable thing)
{
    Console.WriteLine("I am a Payable Thing");
}

Finally, a simple console application that illustrates how these items work and are either statically or dynamically resolved.  The difference between the 'Concrete' functions is shown by the dynamic keyword telling the runtime to resolve this class at run time regardless of it's declaration.  Also, notice the last item is not even a class at all, but rather a dynamic type declared simply to be passed to this helper function.


static void Main(string[] args)
{
    // call writedynamicobject function for all concrete classes
    Account a = new Account();
    WriteDynamicObject(a);
            
    Employee e = new Employee();
    WriteDynamicObject(e);
            
    Customer c = new Customer();
    WriteDynamicObject(c);
 
    //call function for a concrete class, but resolve type at runtime
    Account p = new Payable();
    WriteConcrete(p);
    WriteConcrete((dynamic)p);
    // dynamically create values and pass as a dynamic type.
    WriteDynamicObject(new {Name="TotallyDynamicNonClass", Balance=250});
 
}
 
The output of this project illustrates how the runtime deals with each of these scenarios.


If you are like me, the first thought you have on using the dynamic typing pattern is along the lines of, "Couldn't you just use an interface or inheritance to accomplish the same thing?"  The answer is yes, assuming you are able to know those types at compile time.  But, there are also times where you can't know the definitions at compile time.  You can't compile the internet, but you can interface with it.  I would be remiss if I didn't get into the downsides of this practice as well.  This can open you up to having a program that is hard to maintain, difficult to debug and unit test and many similar issues. But, guns don't kill people, people with guns do.  Dynamic typing doesn't make code difficult to manage, a programmer does those things with his or her architecture.  This is not a magic bullet and should be used with great caution. The reason for using it is that some problems are inherently dynamic (e.g. web requests).  While you may use reflection for this sort of problem today, you may find dynamic typing a more expressive approach to the same problem.  Simply being dynamic in itself is a compelling argument. Reflection introduces a tightly coupled dependency on a static mechanism.  Dynamic methodologies are intent-based and trust the receiver to act upon the passed intent which creates a scalability unachievable by other means.  The source files are available for download here

Tuesday, June 12, 2012

Object Design Principles - Part 5

Dependency Inversion Principle

The DIP states that high level classes should not depend on low level classes.  Both should depend on abstractions.  Details should depend on abstractions.  Abstractions should not depend on details.  The DIP is about reversing the direction of dependencies from higher level components to lower level components such that lower level components are dependent upon only the interfaces owned by the higher level components.  This is a method for moving to a more loosely coupled architecture.  Basically, you have to depend on a standard interface used by objects and not depend on their details.  This one might be best illustrated by example. 

In the following example, the BadCar class is tightly coupled to the actual implementation of the BadMotor function.  This means that these two objects are married, and changes to one directly impact the other.


public class BadMotor
{
    public Boolean Start()
    {
        Console.Write("Starting");
        return true;
    }
}
 
//tightly coupled to details.
public class BadCar
{
    public BadMotor Motor {get;set;}
 
    public Boolean Start(BadMotor badMotor)
    {
        Motor = badMotor;
        return Motor.Start();
    }
}
 
 
While this does function, it creates a dependency relationship between two objects at their implementation level.   This creates hardships for maintenance and scalability long term.   The proper way to build this relationship would be to invert dependencies onto interfaces to ensure no object has knowledge or visibility into implementation of any other object. Consider the following examples:

public interface IEngine
{
    bool Start();
}
 
public interface IGreenEngine : IEngine
{
    bool IsCharged ();
}
 
public class FourCylEngine : IEngine
{
    public bool Start()
    {
        Console.WriteLine("4Cyl Starting");
        return true;
    }
}
 
public class V8Engine : IEngine
{
    public bool Start()
    {
        Console.WriteLine("V8 Starting");
        return true;
    }
}
 
public class HybridEngine : IGreenEngine
{
    public bool Start()
    {
        if (IsCharged())
            Console.WriteLine("Hybrid Starting");
        return true;
    }
    public bool  IsCharged()
    {
        Console.WriteLine("Hybrid is charged");
        return true;
    }
}
 
public class Car
{
    public Car(IEngine engine)
    {
        Engine = engine;
    }
    public IEngine Engine{get ; set ; }
    public Boolean Start()
    {
            
        return Engine.Start();
    }
}
 
I built this interface dependency and inheritance to ensure that objects are loosely coupled and only share an interface.   This allows for actual base implementations to come and go and even be recognized dynamically without causing lower level objects to update their implementation.   Here is an example of hot swapping and scaling with the previously defined objects and interfaces.

class Program
{
      
    static void Main(string[] args)
    {
        //  Cars are only dependant upon an Engine interface
        Car BigThing = new Car(new V8Engine());
        BigThing.Start();
        //  Cars are only dependant upon an Engine interface
        Car SmallThing = new Car(new FourCylEngine());
        SmallThing.Start();
        // Since we have an interface dependency, it is easy to hot swap.
        BigThing.Engine = new HybridEngine();
        BigThing.Start();
    }
}

The output is as follows:


As you can see, this allows for maintainability and long-term scalability by ensuring that the objects stay out of each other's business. By adhering to the spirit of this principle as well as the previous SOLID principles, you can keep your code base healthy and easy to maintain when the requirement changes come.

Friday, June 8, 2012

Object Design Principles - Part 4

Interface Segregation Principle (ISP)

The ISP says that an interface should not become too 'fat' but be split into smaller and more specific interfaces so that only methods that pertain to a client need to be implemented.  You should focus on designing abstractions that have a very small, focused and sleek design.  Basically, no client should be forced to implement methods or properties it does not need to use.  We should always start at the most granular level and extend interfaces as needed.  You can create new interfaces that are extensions, or groupings, of other interfaces to form classes and objects desired.  Rather than forcing everyone to consume the entirety of a polluted interface, you are allowing them to implement an array of more focused interfaces.  I like analogies for getting my hands around design principles.  I think of this one much like eating at a restaurant.  If you sit down and order a burger, how do you react if you are given soup; then a burger, fries, and a coke; then an ice cream sundae?  And you are expected to pay for all of it.  Apparently, the only way to get a burger is to implement the IThreeCourseMeal interface.  If it doesn't make sense in life, it doesn't make sense in design. 

During application design we should pay close attention to how we abstract modules that contain several sub-modules. Granularity is always the side on which to err when doing interface design.  It is much easier to couple interfaces than to decouple a polluted interface (just as it would be very difficult to 'un-salt' your food.)  As I look through existing interfaces, it seems that this principal is easily and repeatedly violated, probably without intent.  In reviewing for this piece, I saw that months ago I created an interface that flagrantly violated this principle as a quick means to an end.  I plan to decouple it as part of this mental exercise.

Using the restaurant analogy above, I created some interfaces that, while silly, illustrate the principle.  First, I would go for the most granular interface that could logically be shared for all iterations of this type.  I landed on a menu item:

public interface IMenuItem
{
    String Item { get; set; }
    String Price { get; set; }
}


Then, I started creating logical abstractions of a menu item into various aspects of a meal:

public interface IEntree : IMenuItem
{
    String CookingInstructions { get; set; }
}
 
public interface ISide : IMenuItem
{
    Boolean IsVeggie { get; set; }
}
 
public interface IDrink : IMenuItem
{
    Int16 CupSize{ get; set; }
}
 
public interface IAppetizer : IMenuItem
{
    //...
}
 
public interface IDessert : IMenuItem
{
    //...
}


Next, I moved onto large interfaces that would have enough real world implementations to justify a single abstraction:

public interface IValueMeal : IEntree, ISide, IDrink
{
    //...
}
 
public interface IThreeCourseMeal : IAppetizer, IEntree, ISide, IDrink, IDessert
{
    //...
}

The advantage is that I can always come in at the implementation level and create my own dynamic abstraction.  Notice which properties' objects are created when I choose to implement the interface:

public class MyCustomMeal : IEntree, IDrink
{
 
    #region IEntree Members
 
    public string CookingInstructions
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
 
    #endregion
 
    #region IMenuItem Members
 
    public string Item
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
 
    public string Price
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
 
    #endregion
 
    #region IDrink Members
 
    public short CupSize
    {
        get
        {
            throw new NotImplementedException();
        }
        set
        {
            throw new NotImplementedException();
        }
    }
 
    #endregion
}

Hopefully, you can see how this principle allows for much scalability and dynamism of types without the inherent bloat from linear bulge.  This is a great principle to keep in focus during design.

Friday, May 25, 2012

Object Design Principles - Part 1

Singular Focus and Coupling


This will be the first installment of a multiple part posting on object design principles.  These are vital to keep in mind as we go through creation of large product platforms with many interaction services and objects that must be maintained and enhanced over time.

Object Responsibility

In my mind, the most vital question you can ask yourself at the outset of an object design is, "What is this object's core responsibility?"  Your entire design should flow from that very basic question. You should consistently look for the most granular object definition possible and work back from that.  It's really easy to get blinded by the vastness of the entire project and the complete set of user stories and completely misjudge where to segregate your logic.  Once you have defined the core responsibility and focus of an object, you can immediately start creating an inheritance path as well as supplemental interfaces to bring your object into full functionality.  This is the most vital step in ensuring a scalable and easily maintainable system long term.  Consider the following basic user requirement:  "I need to be able to view images and apply enhancements to them."  The first thing that comes to my mind is that although the user requirement is to always view images, every image view session will not ultimately result in an image enhancement session.  So, I immediately break into two objects, a viewer and an editor : viewer.  At its core, the viewer object should do nothing more than accept image data and render in a viewable state. The viewer should have no concept of any data or state outside of the image itself.  It should interact via an interface with a standardized image format so that it doesn't need to have any system context. 

The system also should have no specific knowledge of the viewer (more on that when we talk about coupling).  Then, the editor class should start by extending the known viewer class.  It should not extend any operation that pertains to the loading and displaying of the base image.  That aspect of responsibility should be a black box to the editor.  The editor should contain an interface for advertising its list of manipulations as well as a standardized message based interface for executing them.  This object is not responsible for a menu or toolbar system, it is simply an image manipulator requiring system input to launch an execution of its internally known action.  It also would not have any context for displaying an image history listing.  It would maintain a list of events, based on its internally known list of manipulations and allow an outside source to interact with that list via a standardized message or interface.

Loosely Coupled Objects

The main point of the granularity of the design listed above is to ensure a loosely coupled framework.  These controls and objects should all be interacted with via their interface over standardized messages.  If each object is singularly purposed and has a black box for its implementation, the only exposure and ultimate point for breakdown is the interface itself.  The loosely coupled system (or systems) interacts with itself based on standard messages or interfaces. The granularity, once released to production, allows for a dynamically upgradeable system with hot swap components.  In this scenario, we could easily swap out our image viewer or image editor in any given system with a very limited impact on the system as a whole. The change would be contained in a singularly purposed object that is loosely coupled with its housing system.  We would be able to quickly respond to a requirement for viewing a new image format without having to make changes to our image editor control.  Additionally, this transforms every control, service or object in every system into a plausible enterprise level base class by never assuming product knowledge or any aspect of external state.

By thoroughly investigating singular focus and coupling as part of every design, we can work toward a much more stable and dynamic system in the future.

Thursday, April 26, 2012

SOA Discussion

SOA is a constant topic of conversation these days and has become a mindset for people trying to architect systems that are available, dependable, scalable and maintainable.  The trick of discussing SOA at a high level or simply stating that it is your goal is that SOA itself is not easily definable when placed in the paradigm of any individual business or system.  SOA is a conceptual methodology or a philosophy of sorts.  This seems to contribute to the possibility of having your project team actively pursuing a common goal, of which they each have their own interpretation.  As this becomes more of a daily task in reality and less of a mental exercise, it seemed like a good time to lay out what this architecture means to me.  In my mind, SOA can be defined as an architectural means to build a system consisting of many autonomous and focused services.  To architect in SOA you have to start by defining the level at which you want the system in question to be integrated.   Since any business system can be comprised of many smaller systems, on many platforms with many different implementations, it is paramount to focus on an integration interface.  As I have heard said, and love to repeat, "You have to eat your own dog food."  Basically, rather than creating a system and then opening up integration, the systems themselves have to be a packaged consumption of service integration. Rather than get into a semantic argument about the exact definition of a service, for the sake of this discussion, let’s assume that a service is defined as a program that is interacted with via message exchanges.   Services must be designed to be highly available and scalable.  When I speak of being scalable, it is to infer the need to have a consistent and constant means of interacting with the service itself.  The configurations and aggregations of the service are where you should scale out and customize to meet an individual name.  But at the end of the day, the core service should be small, focused and consistent.  It should perform the advertised action entirely and exclusively. This is the Single Responsibility aspect of the SOLID principles, which should be followed as a rule.  Being singularly focused allows for our services to come together to form a loosely-coupled infrastructure, which positions us for the aforementioned scalability and maintainability.  Systems architected with this philosophy result in a network of logical processes and functions that are no longer held prisoner by existing infrastructure or large project migrations.  This allows for individual services to be updated, replaced, rewritten or otherwise reinvented without a direct impact to any integrating processes.  As long as all service interfaces remain consistent and constantly rely upon a messaging system for interaction, the actual logic and heavy lifting of these services becomes completely abstracted behind the interface messages.  This, to me, is the heart of the matter.  Every service, every process and every system, at this point, should be interacting primarily with an eternal set of interface messages with a seeming disregard for the entity with which it is communicating.

The Four Principles of SOA
A generally accepted principle of SOA is the adherence to the four principles of SOA.  We will go through them one by one and try to get to the root of what they mean in spirit and in actuality.

Boundaries Are Explicit
A boundary is really just the dividing wall between a public interface and internal implementation. That concept is fairly straightforward and should be easily grasped.  It is vital that this is followed to allow for dynamic relocation of services, etc.  A good way to grasp this principle is to make sure that a consumer of a service has absolutely no insight into the implementation of the internal process.  The consuming entity should have no control of the performance of the services being consumed.  I would like to take this a little bit further and begin to talk about bidirectional crossing of tier boundaries, but in order to do so, we need to define the terms ‘layer’ and ‘tier’.  When we talk about these items, understand that a ‘layer’ is a logical grouping of code and/or processes.  For instance, a DAL or data access layer is a grouping of functions that interacts with a dataset of one kind or another.  The DAL should provide services/functions that encapsulate all interaction with the dataset to ensure all rules are consistently met and any policy enforcement can happen in a dependable manner.  This has absolutely nothing to do with physical location and arguably can share process space with other layers depending upon the facts of a given situation.  A ‘tier’ on the other hand implicitly indicates a physical location.  In other words, a tier contains one or more layers.  A good rule of thumb is that no process should interact with another process any further out (being toward the consumer) than the tier at which it is running.  This rule is not broken with push notifications, update messages or callbacks; those are different types of communication and are completely acceptable.  This rule ensures that your objects are designed with the appropriate level of encapsulation in mind. For example, consider the following 3 tiers and their logical format.  GUI, BLL and DAL.  The GUI will be the consumer of a service on the BLL, UpdateEmployee.  BLL::UpdateEmployee will in turn be a consumer of DAL::UpdateEmployee.  The argument comes that the Employee entity could have a related EmployeePicture record.  The quick and dirty reaction is to have DAL::UpdateEmployee update the EmployeePicture record directly against the dataset.  A later revised system requirement is that every Employee should have a 1:* relationship with EmployeePicture.  So, the developer creates a BLL::UpdateEmployeePicture along with DAL::UpdateEmployeePicture.  Problem solved.  A consumer can create Employees and EmployeePictures interchangeably.  Another revision requires that every Employee must have a default picture.  So, adhering to good OOP principles, the developer has DAL::UpdateEmployee consume BLL::UpdateEmployeePicture to create the initial record.  This is where we start getting into all kids of trouble.  The tier communication rule is broken. While this is innocuous enough right now, when the next design change requires the Employee record to be updated with a modified date of today each time an EmployeePicture is created, it becomes an issue.  So what do you do?  You can’t have BLL::UpdateEmployeePicture call DAL::UpdateEmployee since it could very likely be the parent origin of the current context.  You can’t have DAL::UpdateEmployeePicture call DAL::UpdateEmployee, since it is likely the origin of this context.  The model is broken.  The ideal methodology here is to have the DAL functions do nothing more than they say they do and have the BLL services be aggregate calls to the DAL.  All synchronous consumption flows inward and is never intermixed across tiers.

Services Are Autonomous
I like to read this one as ‘Do what you say and say what you do, completely.’ A service should perform the task it is designed to perform and never more or less.  The entirety of the process should be documented so that all service consumers are acutely aware of the process intent.  These services should be completely independent of the consuming code as well as any services with which they interact internally.  This allows for a service to be versioned and deployed independently of interacting processes.  This also creates the need for a rule to follow in regards to this principle.  Once and interface is deployed and live consumption is plausible, the interface can’t be modified.  Interfaces can be added and logic abstracted at this layer, but the interface, once published is in fact eternal.  You should also always assume a worst case scenario from the consumer of the service.  This means, don’t count on the data to be valid; don’t assume all values are correct; and don’t assume that the developer of the consuming process has any idea what your service is expecting.  This includes the dependency of functions being called in a certain order to create and maintain scope level variables.  All things that need to be known by a service should either be inherently internal or provided by the consumer.  Create your rules, enforce them internally and raise exceptions when they are not met.  This includes interaction with other services that may not be available.  Never assume that all interactions required will be available.  If the service interacts with something that is currently unavailable, you should have a fail-safe in place.
 
Services Share Schema and Contract, Not Class
Service consumption should be based on contracts, schemas or policies. A good way to stay agnostic in this regard is to communicate using SOAP or XML schema-based messages.  This makes both language and platform a non-factor in your service consumption.  While this is highly dependent upon the need to be available outside of known technologies and platforms, it is always a good mental exercise at design time.  A contract must remain stable over time.  Again, once deployed they must be eternal.  That is probably the most difficult part of this rule.  But, I always like to think of a very simple example for this sort of philosophy.  Consider a light bulb socket.  Light bulbs themselves have changed over time, as have wiring standards, breakers, building codes, etc.  But, a light bulb socket has maintained interoperability with all of these items by simply interacting with electricity on one side and a static interface to a light bulb on the other.  It has no visibility, nor concern with the inner workings of the light bulb, nor does it care about the circuitry of the room in which it is housed.  Its interface, or contract if you will, stays constant and simply works with any input/output that interacts with the known interface.  Always adhere to a good division of internal data and external data.

Service Compatibility Is Based Upon Policy
Honestly, this one is tricky.  I have researched this and the best personal example I can give is how you would use a WCF OData service and a QueryInterceptor to resolve a local security policy.  The intent is obviously to have external, possibly machine-readable policies, governing access and compatibility to certain configurations and aspects of your services.  I struggle with finding real-world examples.  I like using the QueryInterceptor as a good and simple illustration.  With this, you can check the context of the caller and decide whether or not a user in this context should be able to access the query that has been requested.  This seems highly-scalable and very powerful since it completely decouples the services implementation from the policy governing its access.  I think this one will become more useful over time as more and more services adhere to the first three aspects of this article.

Conclusion
Overall, it seems that SOA is a great target to have for architecting a system and should be kept as a standard at all levels.  It will serve to position your system for future growth while ensuring your sanity while trying to balance maintenance and advancing projects.