Welcome to MSDN Blogs Sign in | Join | Help

Fluent Interface for System.Identity – Party Implementation (Part 1)

This latest post on developing a fluent interface for the Oslo System.Identity schema will start an implementation of the Party class. Per the architectural specifications for the fluent interface, the Party class will adhere to the Law of Demeter and “Tell, Don’t Ask. As the Party class is large, and important to the System.Identity model, I’ll tackle Party in a couple of different posts.

 

Party is Central to System.Identity

The System.Identity schema is built around a particular design pattern commonly referred to as the “Party Model”. The Party Model is a powerful solution to a common problem found in software – how do you handle the complex relationships that exist between the actors in a system – especially where actors can be both physical and logical participants. This concept is illustrated in the MSDN documentation on System.Identity’s Party entity:

  • “The directory stores information about digital subjects and resources that have relationships. Different kinds of digital subjects typically share many of the same characteristics – while being different. The System.Identity schema provides a single mechanism for defining all the different kinds of things present in the directory –represented through entities called Kinds. The System.Identity schema represents the common aspect of all digital subjects through an entity called a Party.”

The importance of Party to System.Identity is further illustrated in the following UML representation of part of the System.Identity schema. The UML clearly illustrates the centricity of Party to the System.Identity design:

Parties

 

As the diagram above illustrates, Party is associated with almost every other entity in the System.Identity schema. This makes designing a fluent interface for Party an interesting design exercise.

 

NOTE – For those devotess of Domain-Driven Design (DDD) I will be purposefully ignoring the ORM implications of Party (specifically Aggregates) in terms of Party methods, although use of the Law of Demeter and “Tell, Don’t Ask” produces code that is very conducive to “modern” domain model persistence designs. I’ve been toying with the idea of writing a series to reactoring the fluent interface to adhere to DDD and leverage NHibernate, but that might be a while down the road.

 

The Party Basics

As with the fluent interface implementation of the Kind class, Party’s code will exhibit a certain shape given adherence to “Tell, Don’t Ask”. The following snippet shows the first pass on Party’s code:

   1: public class Party : SystemIdentityBase
   2: {
   3:     public string Name { get; private set; }
   4:     public string DisplayName { get; private set; }
   5:     public string YomiDisplayName { get; private set; }
   6:     public string DescriptiveInformation { get; private set; }
   7:     private Kind Kind { get; set; }
   8:     private Kind PrimaryKind { get; set; }
   9:     private List<Role> Roles { get; set; }
  10:  
  11:     public Party ( string name, string displayName, string yomiDisplayName, string descriptiveInformation, Kind kind, Kind primaryKind )
  12:     {
  13:         ChangeName ( name );
  14:         ChangeDisplayName ( name );
  15:         ChangeYomiDisplayName ( yomiDisplayName );
  16:         ChangeDescription ( descriptiveInformation );
  17:         ChangeKind ( kind );
  18:         ChangePrimaryKind ( primaryKind );
  19:  
  20:         Roles = new List<Role> ();
  21:     }
  22:  
  23:     public void ChangeName ( string name )
  24:     {
  25:         Name = name;
  26:     }
  27:  
  28:     public void ChangeDisplayName ( string displayName )
  29:     {
  30:         DisplayName = displayName;
  31:     }
  32:  
  33:     public void ChangeYomiDisplayName ( string yomiDisplayName )
  34:     {
  35:         YomiDisplayName = yomiDisplayName;
  36:     }
  37:  
  38:     public void ChangeDescription ( string descriptiveInformation )
  39:     {
  40:         DescriptiveInformation = descriptiveInformation;
  41:     }
  42:  
  43:     public bool IsOfKind ( Kind kind )
  44:     {
  45:         return Kind.Equals ( kind );
  46:     }
  47:  
  48:     public void ChangeKind ( Kind kind )
  49:     {
  50:         Kind = kind;
  51:     }
  52:  
  53:     public bool IsOfPrimaryKind ( Kind primaryKind )
  54:     {
  55:         return PrimaryKind.Equals ( primaryKind );
  56:     }
  57:  
  58:     public void ChangePrimaryKind ( Kind primaryKind )
  59:     {
  60:         PrimaryKind = primaryKind;
  61:     }
  62: }

 

In addition to the basic aspects of Party (i.e., attributes of Party), the code snippet above contains a private automatic property for the collection of Roles a Party may play. The design of Party’s interface with respect to the Roles collection will be the subject of the rest of this post.

 

NOTE – The remainder of this series will use simple generic Lists to represent the various collections in the System.Identity schema. The use of Lists is not necessarily optimal, so the fluent interface offers GetHashCode() implementations for those applications that require better than O(n) performance.

 

Telling a Party About its Roles

In the context of “Tell, Don’t Ask” we can think about the Party methods in terms of the specific domain that System.Identity addresses. For example, we could think of the Party interface as a means of facilitating the following scenarios:

  • Dave Langer accepts employment with Microsoft Corporation
  • Determining if Dave Langer is employed
  • Determining if Dave Langer was employed by Microsoft Corporation from MM/DD/YYYY to MM/DD/YYYY
  • Dave Langer terminates his employment with Microsoft Corporation
  • Dave Langer is no longer an Architect on any projects at Microsoft Corporation

First in the above list is providing a method for a Party to assume a new Role. The method implementation is straightforward as illustrated by the following code snippet:

   1: public void AssumeRole ( Role role )
   2: {
   3:     if ( !Roles.Contains ( role ) )
   4:     {
   5:         Roles.Add ( role );
   6:     }
   7: }

 

The next scenario is where “Tell, Don’t Ask” really shines in producing code that just has an OO “feel” to it. The Party class’ public interface will provide two methods for determining what Roles a Party might play:

   1: public bool PlaysRole ( Role role )
   2: {
   3:     return Roles.Contains ( role );
   4: }
   5:  
   6: public bool PlaysRole ( Predicate<Role> matchingSpecification )
   7: {
   8:     Role role = Roles.Find ( matchingSpecification );
   9:  
  10:     if ( role == null )
  11:     {
  12:         return false;
  13:     }
  14:  
  15:     return true; 
  16: }

 

The first method in the code snippet above addresses the scenario of “tell me if Dave Langer is employed”, while the second method supports the scenario of “tell me if Dave Langer was employed by Microsoft Corporation from MM/DD/YYYY to MM/DD/YYYY”.

 

Lastly, Party’s interface will provide some OO goodness for telling a Party to stop playing a Role:

   1: public void StopPlayingRole ( Role role )
   2: {
   3:     Role roleToStopPlaying = Roles [ Roles.IndexOf ( role ) ];
   4:  
   5:     roleToStopPlaying.ChangeEndDate ( DateTime.Now );
   6: }
   7:  
   8: public void StopPlayingRoles ( Predicate<Role> matchingSpecficiation )
   9: {
  10:     List<Role> rolesToStopPlaying = Roles.FindAll ( matchingSpecficiation );
  11:     DateTime timeStamp = DateTime.Now;
  12:  
  13:     foreach ( Role role in rolesToStopPlaying )
  14:     {
  15:         role.ChangeEndDate ( timeStamp );
  16:     }
  17: }

 

As System.Identity supports the concept of “logical deletes” for Roles via start and end dates, the methods above don’t actually remove Role objects from the collection. The first method in the code snippet above implements the scenario of “Dave Langer quit work at Microsoft” and the second method implements the scenario of “Dave Langer is no longer an Architect on any project at Microsoft”.

 

Law of Demeter & Collections

The above snippets illustrate the OO goodness that results from applying “Tell, Don’t Ask” to minimize coupling. However, the practical reality is that sometimes it is really darn handy to get a collection directly from an object in the domain. The reasons for this are many, but the single most common reason is to grab the collection so that it can be iterated over and displayed in a UI. Now, if you’re addicted to design patterns like I am then you’ll immediately jump to patterns like Visitor or Model-View-Presenter (MVP) as potential solutions to this problem that don’t violate the Law of Demeter.

The problem with using Visitor or MVP is that the more they are used to maximize cohesion and reduce coupling, the more complicated the class model becomes. Luckily, the Demeter folks consider containers (which they call “Repetition” classes) as exempt from the Law of Demeter. For those that are interested check out this wiki.

In terms of the Party class this means that we can expose the Party class’ collection of Role object:

   1: public IList<Role> PartyRoles ()
   2: {
   3:     return Roles.AsReadOnly ();
   4: }

 

As the above snippet illustrates, direct exposure of the List would be inappropriate due to the fact that clients could directly add and remove Role objects directly, thereby bypassing the AssumeRole(), StopPlayingRole(), and StopPlayingRoles() methods. Additionally, the code above follows the spirit of the Law of Demeter by using the IList interface to further insulate clients from changes in the Party class implementation.

 

Next Time

More Party implementation goodness.

Stay tuned!

 

A Real World Use For Oslo

I’m going to take a small detour from my series on a fluent interface for Oslo’s System.Identity schema to propose a real world scenario where Oslo could be leveraged. This post has its genesis in Kraig Brockschmidt's recent post “What Exactly Does One Do With ‘Oslo’”. While I think Kraig’s post covers a number of important ideas regarding the potential applications of Oslo, the responses to the post nevertheless contain a strong undercurrent of “Great, I still don’t how I would use Oslo in the real world”.

 

I figured, at the risk of arrogance and ridicule, that I would offer such a scenario.

 

Oslo – It’s About Architecture

As I’ve written about previously, I find Oslo an immensely interesting technology (although at first, like many, I didn’t think much of Oslo). One of the significant triggers for my “flipping the bit” on Oslo was reading Chris Sells’ excellent MSDN article on Oslo. Like anybody who has been following Oslo, I’ve seen all the video and web content illustrating Oslo’s DSL capabilities – and like anybody familiar with ANTLR I was intrigued, but not blown away. However, what Chris’ article showed me was that despite all the focus on what was formally called MGrammar, Oslo is actually most interesting as an accelerator for building metadata-driven applications (OK, metadata-driven applications that leverage DSLs ;-).

 

This is significant because Oslo does not provide a targeted implementation solution like ASP.NET or SQL Server do, Oslo provides a solution to address architectural concerns.

 

Kraig validates this view of Oslo when he writes:

  • “What's more valuable is to create a runtime that effectively implements a class of applications, where each specific application is wholly defined by metadata alone. That is, the runtime is a kind of generic application engine for that class. One essentially configures that generic engine with specific metadata to thereby produce any number of particular, custom "applications" (you know, the thingies that are visible on the screen that users poke at all day). From this one realizes a significant productivity gain in comparison to writing each such application from scratch.”

Those readers familiar with Microsoft will undoubtedly recognize in the passage above some ideas that are akin to the Software Factories approach to improving software development. Like Software Factories, Oslo is an attempt to improve the efficiency and quality of application development via an architecture-centric approach.

 

Real World Oslo – It’s About Reusable Architecture

For the sake of argument, if we accept that Oslo is tool to address architectural, rather than implementation, concerns (check out this post for definitions) then it stands to reason that real world applications of Oslo would involve using the technology to address opportunities that are inherently architectural in nature. 

 

For example, the Software Engineering Institute (SEI) provides just such an opportunity in the concept the SEI calls “software product lines”:

  • “A software product line (SPL) is a set of software-intensive systems that share a common, managed set of features satisfying the specific needs of a particular market segment or mission and that are developed from a common set of core assets in a prescribed way.”

While the software product line concept is similar to Software Factories, SPLs have a much lower barrier to entry and have had documented success in the real world. The following SPL case studies are taken from the book “Software Architecture in Practice”:

  • “Cummins, Inc., was able to reduce the time to it takes to produce the software for a diesel engine from about a year to about a week.“
  • “With a family of satellite ground control systems it commissioned, the U.S. National Reconnaissance Office reports the first product requiring 10% of the expected number of developers and having 90% fewer defects."

As a career Fortune 500 IT weenie, I can attest that there exists a class of applications that fit both the architectural characteristics that Kraig and the SEI describe above – enterprise business applications.

 

Real World Oslo – Building a SPL for Enterprise Business Applications

It is possible (I’m asking for some trust on this ;-) to illustrate through architectural analysis that a software product line for enterprise business applications would focus on building reusable software assets/platforms that are:

  • Multitenant
  • Metadata-driven
  • Capable of automating workflow

The above is obviously a non-exhaustive list of the potential characteristics for an enterprise business application software product line, but it clearly illustrates that Oslo is a potential accelerator for any organization (e.g., a large IT shop or ERP software vendor) that builds enterprise business applications.

As Kraig correctly points out in his blog post, use of Oslo is only realistic in situations where economies of scale are to be gained. The ROI of creating a metamodel, DSL, and runtime using Oslo for a single application will typically not compute. This is where the SPL concept starts to make sense. If an organization will be building multiple enterprise business applications, then the creation of core Oslo architectural assets (i.e., metamodels, DSLs, and runtimes) to be reused across development efforts could drive a favorable ROI – both in terms of overall time to market and quality.

Now I realize that what I’m talking about here won’t apply to a wide swath of Microsoft’s customers. I won’t lie to you. If you’re working in a small IT shop then the current state of the Oslo technology is not likely to be interesting to you. If you’re working for a Gold-certified Partner then the current state of Oslo is also not likely to be interesting to you (although you may want to look at MS CRM as an app plat for your clients ;-).

However, I don’t see this being a problem at all. As I stated above, tools like ASP.NET and SQL Server are implementation solutions and are applicable to a wide swath of Microsoft customer problems while Oslo is only applicable to those customer’s facing the architectural problems that Oslo addresses. Logically, Microsoft developing and selling Oslo (assuming we end up selling it ;-) is no different than Microsoft developing and selling AX.

 

Oh, Wait. I’m Also a Real World Example

Not to be ham-handed, but it seems appropriate to mention that I’m also a real world example for Oslo (although a biased example ;-). One of the things I spend a lot of time thinking about is how to accelerate the efficiency and quality of delivering business systems to Microsoft. As you might imagine, as the world’s largest software company Microsoft has a number of rather unique requirements in terms of its enterprise business applications – but they all share architectural characteristics. As such, I’ve been exploring and watching Oslo with great interest – maybe your organization should as well. 

As always, feedback is greatly appreciated.

Posted by dalanger | 3 Comments

Fluent Interface for System.Identity – Kind’s Expression Builder

<Author’s Note>

It’s been quite a while since my last blog post. The reason for the gap was due to my non-work time being consumed with swimming (some might say wallowing ;-) in the architectural soup writing a ThinkWeek paper related to Microsoft IT (MSIT) software architecture. Writing the paper took quite a bit more effort than I expected, but I found it a highly enjoyable exercise (yes, I know, I have no life). Now that the paper is done, I’m back to finishing up this series on System.Identity.

</Author’s Note>

The last post in this series finished up some of the plumbing aspects of the System.Identity fluent interface, focusing on the impacts of persisting the fluent interface to the Oslo Repository on the implementation of the Equals() and GetHashCode() methods inherited from System.Object. With the details of the ORM persistence for the fluent interface and the definition of the Kind class’ Command-Query API taken care of, it’s time to take a look at the Kind Expression Builder.

 

A Method Chaining Builder for Kinds

The Expression Builder that will be explored in this post is a class that provides a fluent interface for the construction of Kind objects through the use of Method Chaining. Specifically, the desirable end state is for the code that creates Kind objects to look like the following:

   1: Kind kind = new KindBuilder ()
   2:     .IsNamed ( "TestKind" )
   3:     .CanBeDescribedAs ( "SomeDescription" )
   4:     .CanBeIdentifiedByTheKeywords ( "Keyword" )
   5:     .IsStoredInFolder ( 250 )
   6:     .IsOwnedBy ( owningParty );

 

The desired end state code above illustrates the public interface of the KindBuilder class, using this information the following code snippet shows the Method Chaining public interface of KindBuilder:

   1: public class KindBuilder
   2: {
   3:     public KindBuilder IsNamed ( string name )
   4:     { }
   5:  
   6:     public KindBuilder CanBeDescribedAs ( string descriptiveInformation )
   7:     { }
   8:  
   9:     public KindBuilder CanBeIdentifiedByTheKeywords ( string keywords )
  10:     { }
  11:  
  12:     public KindBuilder IsStoredInFolder ( int folder )
  13:     { }
  14:  
  15:     public KindBuilder IsOwnedBy ( Party owner )
  16:     { }
  17: }

 

The code above is rather straightforward, with the only thing worthy of note is that each of KindBuilder’s public methods return back an instance of KindBuilder. As one might imagine, this is the “secret sauce” that allows Method Chaining to work.

However, the public interface of KindBuilder isn’t yet complete. While the code snippet immediately above addresses the Method Chaining aspect of KindBuilder’s public interface, line #1 of the desirable end state code snippet clearly illustrates that a KindBuilder instance gets converted to a Kind instance at the completion of the method chain. C#’s implicit operator makes this kind of goodness a snap to implement:

   1: public static implicit operator Kind ( KindBuilder builder )
   2: { }

 

The Complete KindBuilder

With the public interface of KindBuilder defined, all that is left is to add some simple state to the class and then implement the implicit operator. The following illustrates the complete KindBuilder class:

   1: public class KindBuilder
   2: {
   3:     private string Name { get; set; }
   4:     private string DescriptiveInformation { get; set; }
   5:     private string Keywords { get; set; }
   6:     private int Folder { get; set; }
   7:     private Party Owner { get; set; }
   8:  
   9:     public KindBuilder IsNamed ( string name )
  10:     {
  11:         Name = name;
  12:         
  13:         return this;
  14:     }
  15:  
  16:     public KindBuilder CanBeDescribedAs ( string descriptiveInformation )
  17:     {
  18:         DescriptiveInformation = descriptiveInformation;
  19:  
  20:         return this;
  21:     }
  22:  
  23:     public KindBuilder CanBeIdentifiedByTheKeywords ( string keywords )
  24:     {
  25:         Keywords = keywords;
  26:  
  27:         return this;
  28:     }
  29:  
  30:     public KindBuilder IsStoredInFolder ( int folder )
  31:     {
  32:         Folder = folder;
  33:  
  34:         return this;
  35:     }
  36:  
  37:     public KindBuilder IsOwnedBy ( Party owner )
  38:     {
  39:         Owner = owner;
  40:  
  41:         return this;
  42:     }
  43:  
  44:     public static implicit operator Kind ( KindBuilder builder )
  45:     {
  46:         return new Kind ( builder.Folder, builder.Name, builder.DescriptiveInformation, builder.Keywords, builder.Owner );
  47:     }
  48: }

 

For those that are interested, code for the SystemIdentityBase, Kind, and KindBuilder classes (with unit tests) is available for download from my SkyDrive. The link to the .ZIP is located a the bottom of this post.

 

Next Time

The subject of the next post will be coverage of the System.Identity Party class. As the models for System.Identity illustrate, Party is a central concept in System.Identity. Working the Party class using the architectural specifications for the fluent interface should be an interesting design exercise.

 

SkyDrive Files

Fluent Interface for System.Identity – M, Persistence, & GetHashCode()

As I wrote about last time, leveraging the System.Identity schema with the Oslo Repository introduces some ORM database persistence considerations into the design of the fluent interface. In the last article I introduced how to override the Equals() method inherited from System.Object. In accordance with MSDN guidance, I’ll be writing an overload of the GetHashCode() method inherited from System.Object that, like the Equals() override, addresses the ORM considerations of the fluent interface.

As with the last post, I’ll be leveraging the excellent coverage of the GetHashCode() method in the book “Effective C#”.

In looking at the considerations for an overload of GetHashCode(), the fluent interface code must adhere to the following rules:

  1. If two objects are equal they must generate the same hash code
  2. The hash code is an invariant for an object – meaning that if even if fields on the object are changed, the hash code always remains the same
  3. The hash function should generate a random distribution of integer values – this ensures efficiency (aka read less collisions in a hash table) so it is more desirable than a hard and fast rule

Given that our fluent interface is essentially a runtime representation of the System.Identity schema in the Oslo Repository, the Id field (which is populated by SQL Server when objects are persisted the first time) qualifies as the hash code source for fluent interface objects that are rehydrated from the Oslo Repository. However, the Id field won’t work for objects that haven’t yet been persisted to the Repository.

Ergo, our GetHashCode() implementation will need to handle two primary objects states – persisted and non-persisted.

 

The State of the Hash

Addressing this split state requirement necessitates the use of a member variable, so for the time being I’ll locate this new field in the SystemIdentityBase class so that all the fluent interface classes can inherit it:

   1: public abstract class SystemIdentityBase
   2: {
   3:     protected Int64? Id { get; private set; }
   4:     protected int Folder { get; private set; }
   5:     private int? BaseHashCode { get; set; }
   6:  
   7:     // Rest of code removed for brevity
   8: }

 

As the above code snippet illustrates, I’ll use a nullable integer field to store the hash code for fluent interface objects that haven’t yet been assigned an Id value by the Oslo Repository (SQL Server).

I’ll continue to leverage the SystemIdentityBase class for the GetHashCode() implementation:

   1: public override int GetHashCode ()
   2: {
   3:     if ( BaseHashCode.HasValue )
   4:     {
   5:         return BaseHashCode.Value;
   6:     }
   7: }

 

Simple enough – if it isn’t null, use the BaseHashCode for the return value of the GetHashCode() method. Putting this first in the method implementation ensures compliance with rule #2 above.

The next step is to address the situation where a fluent interface object has been loaded from the Oslo Repository. In this case I’ll use the hash code of the Id field as the hash code for the object:

   1: if (Id.HasValue)
   2: {
   3:     return Id.GetHashCode();
   4: }

 

As I know that the Oslo Repository masters the Id field (not to mention that fact that it’s marked private and can’t be altered), the usage of the Id field’s hash code addresses rules #1 and #2 above.

Lastly, I need to handle the situation where a fluent interface object is being stuck in a hash table, but hasn’t been persisted yet. To keep things simple (and correct), I’ll punt in this case to the System.Object implementation of GetHashCode(). The following snippet shows the complete method implementation:

   1: public override int GetHashCode ()
   2: {
   3:     if ( BaseHashCode.HasValue )
   4:     {
   5:         return BaseHashCode.Value;
   6:     }
   7:  
   8:     if (Id.HasValue)
   9:     {
  10:         return Id.GetHashCode();
  11:     }
  12:     else
  13:     {
  14:         BaseHashCode = base.GetHashCode();
  15:  
  16:         return BaseHashCode.Value;
  17:     }
  18: }

 

Now I’ve got a reusable implementation of GetHashCode() that all the fluent interface classes will get for “free”.

 

Houston, We Have a Problem

With this implementation of GetHashCode() sitting in the SystemIdentityBase class I’ve got a bit of a problem. In the last post I placed the Equals() override in the Kind class. Looks like some quick refactoring is in order.

In looking at the Equals() code, most of it is easily transferrable to the SystemIdentityBase class. After some quick VS magic I have the following method added to SystemIdentityBase:

   1: public override bool Equals ( object obj )
   2: {
   3:     if ( obj == null )
   4:     {
   5:         return false;
   6:     }
   7:  
   8:     if ( ReferenceEquals ( this, obj ) )
   9:     {
  10:         return true;
  11:     }
  12:  
  13:     if ( this.GetType () != obj.GetType () )
  14:     {
  15:         return false;
  16:     }
  17:  
  18:     Kind otherKind = obj as Kind;
  19:  
  20:     if ( Id.HasValue && otherKind.Id.HasValue && ( Id.Value == otherKind.Id.Value ) )
  21:     {
  22:         return true;
  23:     }
  24:  
  25:     return Name == otherKind.Name &&
  26:            Keywords == otherKind.Keywords &&
  27:            Owner.Equals ( otherKind.Owner );
  28: }

 

The problem arises on lines 18-27 in the snippet above – this is code specific to the Kind class. What I need is for SystemIdentityBase to provide an Equals() implementation that could be overridden on a class-by-class basis. Some minor tweaks and a quick virtual method should do the trick:

   1: public override bool Equals ( object obj )
   2: {
   3:     if ( obj == null )
   4:     {
   5:         return false;
   6:     }
   7:  
   8:     if ( ReferenceEquals ( this, obj ) )
   9:     {
  10:         return true;
  11:     }
  12:  
  13:     if ( this.GetType () != obj.GetType () )
  14:     {
  15:         return false;
  16:     }
  17:  
  18:     SystemIdentityBase otherObject = obj as SystemIdentityBase;
  19:  
  20:     if ( Id.HasValue && otherObject.Id.HasValue && ( Id.Value == otherObject.Id.Value ) )
  21:     {
  22:         return true;
  23:     }
  24:  
  25:     return CompareObjectMembers ( otherSystemIdentityBase );
  26: }
  27:  
  28: protected virtual bool CompareObjectMembers ( SystemIdentityBase otherObject )
  29: {
  30:     return false;
  31: }

 

I like it. The fluent interface is taking on a “frameworky” vibe that just gives an OO bigot like me a deep sense of goodness (it’s sad, I know). All fluent interface classes will now inherit ORM-aware implementations of Equals() and GetHashCode() and have the option of overriding the Equals() functionality if needed.

As a last step I’ll remove the Equals() implementation out of the Kind class and add the following override to the Kind class:

   1: protected override bool CompareObjectMembers ( SystemIdentityBase otherObject )
   2: {
   3:     Kind otherKind = otherObject as Kind;
   4:  
   5:     return Name == otherKind.Name &&
   6:            Keywords == otherKind.Keywords &&
   7:            Owner.Equals ( otherKind.Owner );
   8: }

 

Houston, We’re Not Quite Done

Some readers will unlikely notice that this last code snippet breaks rule #1 listed above. Not a problem, I’ll refactor a little OO goodness into the GetHashCode() method to address the problem:

   1: public override int GetHashCode ()
   2: {
   3:     if ( BaseHashCode.HasValue )
   4:     {
   5:         return BaseHashCode.Value;
   6:     }
   7:  
   8:     if ( Id.HasValue )
   9:     {
  10:         return Id.GetHashCode ();
  11:     }
  12:     else
  13:     {
  14:         BaseHashCode = GetBaseHashCode ();
  15:  
  16:         return BaseHashCode.Value;
  17:     }
  18: }
  19:  
  20: protected virtual int GetBaseHashCode ()
  21: {
  22:     return base.GetHashCode ();
  23: }

 

Excellent. As with the Equals() method there’s a default implementation that will work with a large number of the fluent interface classes, but I’ve provided a nice extensibility point for classes that need different behavior.

To wrap up this post I’ll add a override to the Kind class for the GetHashCode() functionality that it needs:

   1: protected override int GetBaseHashCode ()
   2: {
   3:     int hash = 23;
   4:  
   5:     hash = ( ( hash << 5 ) * 37 ) + ( Name == null ? 0 : Name.GetHashCode () );
   6:     hash = ( ( hash << 5 ) * 37 ) + ( Keywords == null ? 0 : Keywords.GetHashCode () );
   7:     hash = ( ( hash << 5 ) * 37 ) + ( Owner == null ? 0 : Owner.GetHashCode () );
   8:  
   9:     return hash;
  10: }

 

The algorithm above I gleaned from an excellent post that interested folks can read here. Please note that I do not profess to be a hash code algorithms expert, however the code snippet above doesn’t seem to far out of whack from a number of articles/posts I’ve read on the subject.

 

Next Time

For my next post in the series I’ll take a look at an Expression Builder for the Kind class.

Until next time, thanx for reading!

Fluent Interface for System.Identity – M, Persistence, & Equals()

As I wrote in Part 2 of the series, System.Identity ships in the latest Oslo CTP as part of the Oslo Repository. This has the direct effect of introducing ORM database persistence considerations into the design of the System.Identity fluent interface I’ve been crafting.

One of these considerations has already manifested in the following snippet of seemingly straightforward code:

   1: public bool IsOwnedBy ( Party owner )
   2: {
   3:     if ( Owner == null || owner == null )
   4:     {
   5:         return false;
   6:     }
   7:     else
   8:     {
   9:         return Owner.Equals ( owner );
  10:     }
  11: }

 

In the snippet above, line #9 evaluates the equality of the object’s Owner property (as an instance of the Party class) vis-à-vis the passed-in owner parameter.

As it turns out, the Equals() and GetHashCode() methods become quite interesting when dealing with objects that are dehydrated to, and rehydrated from, a database. The subject of this post will be outlining an implementation of Equals() that will work correctly with the fluent interface and a persistence mechanism (e.g., NHibernate) that might be used to store and retrieve objects from the Oslo Repository. My next post will tackle an similar implementation of GetHashCode().

 

It’s All About the Id

While Oslo’s M language can be used as a straight-up textual modeling language, M has been deliberately designed to make using a SQL Sever database as a model repository incredibly easy. In line with this design goal, M supports a number of language features that directly enable model persistence in SQL Server.

From the M for the Oslo Repository in the May CTP, I offer the HasFolderAndAutoId.m file:

   1: //-----------------------------------------------------------------------------
   2: // Copyright (c) Microsoft Corporation.  All rights reserved.
   3: //-----------------------------------------------------------------------------
   4:  
   5: module System 
   6: {
   7:     export HasFolderAndAutoId;
   8:  
   9:     // Mixin used to include a SQLServer-managed numeric identifier and a folder reference.
  10:     // Use this mixin when defining normal content types or extents. 
  11:     type HasFolderAndAutoId : HasFolder
  12:     { 
  13:         Id : Integer64 => AutoNumber();
  14:         
  15:     } where identity Id; 
  16:     
  17: }

The HasFolderAndAutoId is used as a mixin by all the extents within the System.Identity schema and clearly illustrates that the Id field is used to store a SQL Server-managed identity field. This has particular ramifications when considering what it means for one object instance to be equal to another in the fluent interface.

At base, the problem stems from the fact that the primary means of establishing equality between two System.Identity objects at runtime is the value of the Id field and not the memory address of the object instances – the same row in a database table can be instantiated as more than one object in memory. Since establishing this ‘database equivalence’ is not the default behavior of the Equals() method inherited from System.Object, some custom code is required to ensure that the fluent interface works correctly.

Just to make things a little more interesting, a System.Identity object’s Id field is not actually populated with a value until the first time the object is saved to SQL Server. However, at runtime we may very well have legitimate need to call the Equals() method before the objects are saved. As such, we need an Equals() implementation that handles both states – persisted objects (with Id values) and non-persisted objects (no Id values assigned yet).

To address the no Id situation I’ll just make the Id field of the SystemIdentityBase class (which the Kind class inherits from) a nullable field. Here’s the updated code:

   1: public abstract class SystemIdentityBase
   2: {
   3:     protected Int64? Id { get; private set; }
   4:  
   5:     // Rest of code omitted
   6: }

 

Handling Reflexivity

OK, with that taken care of, I can stub in some of the no-brainer code for the Equals() method implementation. For those readers that are interested, the book “Effective C#” has excellent coverage of overriding the Equals() method. The code that follows borrows heavily from the book’s goodness:

   1: public override bool Equals ( object obj )
   2: {
   3:     if ( obj == null )
   4:     {
   5:         return false;
   6:     }
   7:  
   8:     if ( ReferenceEquals ( this, obj ) )
   9:     {
  10:         return true;
  11:     }
  12:  
  13:     if ( this.GetType () != obj.GetType () )
  14:     {
  15:         return false;
  16:     }
  17:  
  18:     throw new NotImplementedException ();
  19: }

Lines 3-11 above are textbook C#, but the code on line 13-16 is interesting. If you take a look at MSDN’s coverage of overriding Equals() there’s this interesting little tidbit:

  • x.Equals(y) returns the same value as y.Equals(x).

This has some interesting ramifications on the implementation of the Equals() override. The bullet above prescribes that overrides of Equals() have to support reflexivity. When one considers polymorphic inheritance, this gets a little complicated. Take, for example, two classes where one class (call it ‘B’) inherits from another (call it ‘A’). Using these hypothetical classes, the bullet above prescribes that the instance call of ‘a.Equals(b)’ must return the same value as the instance call of ‘b.Equals(a)’. This example illustrates that 100% reflexivity cannot be provided unless we consider only exact types in our Equals() overrides (again, take a look at “Effective C#” for great coverage of this topic).

The code in lines 13-16 ensures that only objects that are of the exact same type continue on for further Equals() processing.

 

Addressing Database Equivalence

Given the starting code above, I can add the following to the Equals() method:

   1: Kind otherKind = obj as Kind;
   2:  
   3: if ( Id.HasValue && otherKind.Id.HasValue && ( Id.Value == otherKind.Id.Value ) )
   4: {
   5:     return true;
   6: }

Here we address the ramifications of M-based persistence in SQL Server. Essentially, the code on line 3 in the snippet above says that two Kind objects in memory are equal if they have the same SQL Server-controlled Id (which implies that both have non-null Id fields).

No rocket science here.

 

The End Game

Lastly, the Equals() method handles the case where two non-null Kind objects are being compared, the two objects are at different memory addresses, and one of them (or both) doesn’t have an Id populated by SQL Server. Here’s the last of the code:

   1: return Name == otherKind.Name &&
   2:        Keywords. == otherKind.Keywords &&
   3:        Owner.Equals ( otherKind.Owner );

The code snippet above clearly illustrates that I’m taking the point of view that two Kind object are equal if the Name, Keywords, and Owners are equal (given the constraints listed immediately above the snippet).

This is purely a call on my part since System.Identity does not (to my knowledge) provide any guidance on the equivalence of the extents defined in the schema.

Just for the sake of completeness, here’s the full method in a single listing:

   1: public override bool Equals ( object obj )
   2: {
   3:     if ( obj == null )
   4:     {
   5:         return false;
   6:     }
   7:  
   8:     if ( ReferenceEquals ( this, obj ) )
   9:     {
  10:         return true;
  11:     }
  12:  
  13:     if ( this.GetType () != obj.GetType () )
  14:     {
  15:         return false;
  16:     }
  17:  
  18:     Kind otherKind = obj as Kind;
  19:  
  20:     if ( Id.HasValue && otherKind.Id.HasValue && ( Id.Value == otherKind.Id.Value ) )
  21:     {
  22:         return true;
  23:     }
  24:  
  25:     return Name == otherKind.Name &&
  26:            Keywords. == otherKind.Keywords &&
  27:            Owner.Equals ( otherKind.Owner );
  28: }

 

Next Time

As I mentioned above, the subject of my next post will be an implementation of GetHashCode() that will address the ramifications of M-based persistence in SQL Server.

Stay tuned!

Fluent Interface for System.Identity – Kind Command-Query API

Part 1 of this series functioned as an introduction to the motivations for creating a fluent interface for Oslo’s System.Identity. Part 1 also covered a number of architectural and design specifications that will be followed in the shaping of the interface’s code. In this post I’ll continue the crafting of the fluent interface by exploring an implementation of the Kind command-query API.

 

Refactoring the Base

Before I tackle the Kind class, I need to spend a little bit of time refactoring the SystemIdentityBase class that I developed in Part 1. Specifically, the class needs to be changed to more accurately reflect it’s use as a base class for command-query API child classes in the fluent interface. The code snippet below illustrates the latest rev of the SystemIdentityBase class:

   1: public abstract class SystemIdentityBase
   2: {
   3:     protected Int64 Id { get; private set; }
   4:     protected int Folder { get; private set; }
   5:  
   6:     public SystemIdentityBase ()
   7:     {
   8:         MoveToFolder ( 100 );
   9:     }
  10:  
  11:     public SystemIdentityBase ( int folder )
  12:     {
  13:         MoveToFolder ( folder );
  14:     }
  15:  
  16:     public bool IsInFolder ( int folder )
  17:     {
  18:         return Folder == folder;
  19:     }
  20:  
  21:     public void MoveToFolder ( int folder )
  22:     {
  23:         Folder = folder;
  24:     }

As the snippet above illustrates, the SystemIdentityBase class’ properties have been refactored to allow child classes access to the ‘get’ properties. As we will see later in the series, direct access to these properties will make future code much cleaner without fracturing the OO design. The code snippet also illustrates the refactoring of the class constructors to use the MoveToFolder () method. This refactoring centralizes the ‘set’ functionality in a single location, thereby allowing future logic to reside in a single place – not rocket science to be sure, but nice nevertheless.

 

Breaking “Tell, Don’t Ask”

Now that we have our base class refactored, we can take a stab at the Kind class. The very first thing that we’ll do with the Kind class is break “Tell, Don’t Ask”:

   1: public class Kind : SystemIdentityBase
   2: {
   3:     public string Name { get; private set; }
   4:     public string DescriptiveInformation { get; private set; }
   5: }

Hopefully what the code snippet above illustrates is that there are times when it is appropriate from an OO design perspective to allow clients to ask an object about the object’s state. I would argue that line #3 in the snippet reflects very much the way things work in the real world and, therefore, is good OO design.

Think about the legal system here in the US. When in a court of law a witness is not asked a series of questions (e.g., “Is your name John?”, “Is your name David?”) to establish the witness’ identity – the witness states their name for the record. Additionally, changing one’s legal name in the US is not a trivial affair – there is a process involved that sometimes rejects the name change (although my understanding is that this is rare).

These concepts are modeled in the code snippet above by allowing public read access to the Name property, but making changes to Name private.

The same real-world experience is applied to a Kind’s DescriptiveInformation. In the real world no one is asked “Are you male?” or “Is your weight 187 pounds?”. As with names, descriptive information is directly solicited in the real world. As those of us who have tried to lose weight know, it is often a nontrivial effort to change our descriptive information as well :-).

The remaining two properties of the Kind class don’t fall into the same category as Name and DescriptiveInformation so I’ll make them private:

   1: public class Kind : SystemIdentityBase
   2: {
   3:     public string Name { get; private set; }
   4:     public string DescriptiveInformation { get; private set; }
   5:     private string Keywords { get; set; }
   6:     private Party Owner { get; set; }
   7: }

 

Back to “Tell, Don’t Ask”

In accordance with the “Tell, Don’t Ask” architectural specification, I’ll add some methods to the Kind class’ interface:

   1: public void ChangeName ( string name )
   2: {
   3:     Name = name;
   4: }
   5:  
   6: public void ChangeDescription ( string descriptiveInformation )
   7: {
   8:     DescriptiveInformation = descriptiveInformation;
   9: }
  10:  
  11: public void ChangeKeywords ( string keywords )
  12: {
  13:     Keywords = keywords;
  14: }

The ChangeName(), ChangeDescription(), and ChangeKeyword() methods are straightforward, so I won’t belabor them. The following methods that I’ll add are far more interesting:

   1: public bool MatchesKeywords ( Func<string, bool> matchingSpecification )
   2: {
   3:     return matchingSpecification ( Keywords );
   4: }
   5:  
   6: public bool MatchesKeyword ( string keyword, KeywordComparisonType comparisonType )
   7: {
   8:     switch ( comparisonType )
   9:     {
  10:         case KeywordComparisonType.CaseSensitive:
  11:             return Keywords.Contains ( keyword );
  12:         case KeywordComparisonType.CaseInsensitive:
  13:             return Keywords.ToLower ().Contains ( keyword.ToLower () );
  14:         default:
  15:             throw new ArgumentOutOfRangeException ();
  16:     }
  17: }

The MatchesKeywords() method, arguably, is the epitome of “Tell, Don’t Ask” – it allows a client to provide the exact means of deciding a keyword match through the use of a delegate. By way of comparison, the MatchesKeyword() method doesn’t use a lot of “tech” to get the job done. For those that are curious about the implementation of the switch statement in the snippet above, I would refer you to “Effective C#”, Item #8 for more info.

The following snippet finishes up this rev of the Kind class by addressing the Owner functionality:

   1: public void ChangeOwner ( Party owner )
   2: {
   3:     Owner = owner;
   4: }
   5:  
   6: public bool IsOwnedBy ( Party owner )
   7: {
   8:     if ( Owner == null || owner == null )
   9:     {
  10:         return false;
  11:     }
  12:     else
  13:     {
  14:         return Owner.Equals ( owner );
  15:     }
  16: }

Generally speaking, there’s not much in the snippet above that we haven’t seen already. The one exception to this is line #14 – the call to the Equals() method of the Owner object (which is an instance of the Party class). While this line of code appears trivial, it does in fact have some very interesting ramifications to the fluent interface implementation.

These ramifications are born of the fact that System.Identity is shipped as part of the latest Oslo CTP’s Repository – which means that the fluent interface must also address concerns related to persistence.

 

Next Time

For the next post in the series I’ll address some of the ORM considerations that arise from Oslo’s use of SQL Server as the System.Identity persistence mechanism.

Stay tuned!

Fluent Interface for System.Identity – The Basics

<Author’s Note>

A very talented Developer I know just recently gave me some very succinct feedback on my blog - “good blog…too long”.

As I respect this Developer’s opinion quite highly (not to mention I always try to listen to Developers), I am going to start putting his suggestion into practice by chunking further posts into smaller pieces.

It is worthy to note that these smaller pieces will quite likely lead to more frequent posts – apologies in advance for any RSS bloat.

</Author’s Note>

 

Introduction

As I’ve written about previously, I’m highly interested in DSLs and Oslo’s System.Identity schema. Based on these two interests I recently decided that I would start exploring a Fluent Interface as an Internal DSL for the System.Identity schema. My motivations for this are two-fold:

  1. Give myself an excuse to play around with actual code
  2. Attempt to illustrate the power of the Party Model (via System.Identity) using an avenue that may be more appealing than (as much as it pains me to type this ;-) UML

Being both an Architect and unrepentant Object-Oriented bigot, I’ve convinced myself that this exploration will adhere to number of “modern” OO Software Engineering best practices. My intent with taking the tack is to hit a number of coding topics that are near and dear to my cold and black Architect heart. We shall see if I will be successful in this regard.

 

Fluent Interface Architectural/Design Principles

Throughout this subseries on System.Identity I plan to adhere to a number of Architectural/Design specifications in crafting the interface code:

  1. The architectural specification of the Law of Demeter
  2. Martin Fowler’s design specification for a Parsing Layer
  3. Domain-Driven Design’s (DDD’s) design specification for Aggregates
  4. The Pragmatic Bookshelf’s design specification for “Tell, don’t ask
  5. Design specifications from the concepts included in Prefactoring

As we shall see, application of these five specifications will have very interesting consequences on the shape of the code. Indeed, I wouldn’t be surprised at all if the code’s shape ends up looking quite a bit different from “run of the mill” C#. One potential effect of this might be that the Command-Query API will tend to look more like a Fluent Interface. 

To be honest, I expect that quite a number of readers will disagree with either my interpretations of these specifications, or they will disagree with my practical application of these specifications in the code. Some readers will undoubtedly disagree with both.

This is 100% by design and I sincerely look forward to any discussion on these topics.

 

Starter Class

As we saw in the UML models of System.Identity, every class had two basic attributes – an Id field and a Folder field. For the sake of convenience we’ll create an abstract base class that encapsulates this universality:

 

   1: public abstract class SystemIdentityBase
   2: {
   3:     private Int64 Id { get; set; }
   4:     private int Folder { get; set; }
   5:  
   6:     public SystemIdentityBase ()
   7:     {
   8:         Folder = 100;
   9:     }
  10: }

What some folks might find interesting in the snippet above is that the automatic properties on lines 3 and 4 are marked private. One of the design specifications from Prefactoring is that it is better to put a level of indirection between the state of an object and the object’s operations. In terms of early versions of C# that meant only accessing a class’ member variables via a property – even in private helper methods.

Since automatic properties can’t hold any business logic or data access code, I would argue that automatic properties are nothing more than syntactic sugar for old school member variables.  Therefore, under Prefactoring thinking, an additional level of indirection is required. In accordance with this design specification, the automatic properties are marked private.

We can now augment SystemIdentityBase’s public interface with some methods that adhere to Prefactoring, the Law of Demeter and the “Tell, don’t ask” specifications:

   1: public bool IsInFolder ( int folder )
   2: {
   3:     return Folder == folder;
   4: }
   5:  
   6: public void MoveToFolder ( int folder )
   7: {
   8:     Folder = folder;
   9: }

The IsInFolder() method conforms to “Tell, don’t ask” specification by disallowing clients of SystemIdentityBase instances from directly retrieving the Folder value and basing decisions on that value. To use a conversational metaphor, this results in statements along the lines of “Tell me if you’re currently in this folder” rather than “Give me your current folder”. This is a core aspect of “Tell, don’t ask” and simultaneously increases cohesion and lowers coupling in the code. Another benefit of shaping the code in this manner is an increase in the “fluency” of the Command-Query API.

In terms of the Law of Demeter, the IsInFolder() method is compliant with the architectural specification because it prevents code like the following:

   1: var testValue = 125;
   2:  
   3: if ( testValue == someEntity.Folder )
   4: {
   5:     // Do some cool logic here
   6: }

While the snippet above seems innocuous enough, what really happens behind the scenes is the following:

   1: var testValue = 125;
   2:  
   3: if ( someEntity.Folder.Operator == ( testValue ) )
   4: {
   5:     // Do some cool logic here
   6: }

Strictly speaking, this “two dot” situation is violation of the Law of Demeter (being quite the stickler here, aren’t I? ;-). Compare the above code to the following:

   1: var testValue = 125;
   2:  
   3: if ( someEntity.IsInFolder ( testValue ) )
   4: {
   5:     // Do some cool logic here
   6: }

Call me an OO junkie, but I just like the look of this last code snippet a lot better – even though I’ve personally written a ton of code that uses the straight “property-ask, then compare” approach. The code just feels like OO should. I also know that from first-hand experience that this style of code is easier to maintain over long periods (say 5 year or so) in Production.

Compared to IsInFolder(), the MoveToFolder() method is a straight forward “setter” method for the Folder automatic property and really doesn’t bear a lot of explanation. That being said, it is interesting to note that we again have another increase in the fluency of the Command-Query API from compliance with the chosen architectural/design specifications. Take the following code snippet as an example:

   1: var testValue = 125;
   2:  
   3: someEntity.MoveToFolder ( testValue );

For the time being I’ll leave the Id fields of the entities alone. I’ve got two main reasons for this:

  1. The Ids are really just RDBMS implementation details – a good ORM framework (e.g., NHibernate) usually takes care of the administration of these things transparently
  2. Leaving out makes the posts shorter and we don’t miss any of the goodness

 

Next Time

For the next post in the series we’ll move to take a look at an implementation of the Command-Query API Kind class.

Until next time, thoughts greatly appreciated!

The Formal Goodness of Agile Software Architecture – Part 2

In Part 1 of this short series I discussed an article that proposes the Intensional/Locality Thesis for formally distinguishing between what is Architecture and what is Design. Part 1 also covered how the Thesis has shaped my thinking about the role of the Architect and Software Architecture within an Agile project team.

As I was writing Part 1, specifically the bulleted lists of architectural specifications, it occurred to me that I had used a number of mechanisms on past projects to communicate Architecture. These mechanisms have included:

  • Whiteboard conversations (my personal favorite)
  • Word documents using text (my least favorite)
  • Visio diagrams (OK, but lacks some rigor)
  • UML models (another personal favorite)

It was towards the end of writing Part 1 that I decided that in fact there would be two posts – Part 1 describing how the Intensional/Locality Thesis reshaped my thinking and this post describing how to use UML models to communicate architectural specifications (in compliance with the Thesis) in an Agile way.

As I was thinking about the prep work for this post, I figured I would have to fire up Sparx and create a UML model to use as a case study. However, as I got prepared to do some modeling it occurred to me that I might already have something better.

A number of months back I created a sample UML model to illustrate one way that UML could be used for Software Architecture on an Agile project. The main goal of the sample was to illustrate how UML can be a powerful communication and documentation tool that enhances the agility of a team – how Architecture can be a point of leverage.

Intrigued by the reuse potential, I’ve decided to use this UML model to see how it stands up to the ideas discussed in Part 1. What follows in this post is the unaltered UML model I created, interpreted in the context of the Intension/Locality Thesis.

NOTE – There is a complete HTML representation of this UML model available from my SkyDrive. The link to the .ZIP is located at the bottom of this post.

 

The Conceptual View

The first item of interest in the UML model is the Conceptual View. The intent of this model is to communicate the overall architecture of the software at a relatively high level of abstraction. While not 100% correct from a UML standards perspective, this model leverages the UML Component diagram as the means of communication. The Conceptual View is depicted below:

ConceptualView

When using the concepts in Part 1 to interpret the model depicted above, we can quickly identify that the Conceptual View declares a number of architectural specifications. We can also identify that these specifications adhere to the two main categories described in Part 1:

  • “Traditional” architectural specifications (e.g., Pipes and Filters)
  • Design specifications (aka Patterns) that have been elevated to architectural specifications

The first thing that is worthy to note is that the Conceptual View prominently lays out the first architectural specification – the use of a Layered Architecture.

Additionally, the Conceptual View incorporates a large number of constraints on the structure of the software:

  • The Presentation Layer depends upon the Services Layer
  • The Services Layer depends upon the Application Layer
  • The Application Layer depends on a Data Access Layer (DAL)
  • The Application Layer depends upon the following:
    • The Exception Handling Application Block of the Enterprise Library
    • The Logging Application Block of the Enterprise Library
  • The DAL depends on the following:
    • The Caching Application Block of the Enterprise Library
    • NHibernate framework

That’s a lot of architectural goodness derived from a single diagram, but is typical of the large amount of leverage I’ve seen in crafting architectures that are replete with Design Patterns.

As you might imagine, a full-blown collection of architectural specifications would likely include guidance on how Repositories should be implemented using NHibernate, how the Exception Handling Application Block will be configured, how the Caching Application Block should be used, etc.

For the sake of brevity the UML model isn’t 100% complete, but it does illustrate a very powerful mechanism that UML has for modeling architectural specifications – UML patterns.

 

Repository Architectural Specification

As the Conceptual View illustrates, there is an architectural specification for the use of the “Repository Pattern”. As covered in Part 1 of the series, I tend to think that one of the duties of the Agile Architect is transforming appropriate Design Patterns (which are inherently design specifications under the Intensional/Locality Thesis) into architectural specifications. This transformation is attained mainly through moving the scope of a Design Pattern from local to non-local. As illustrated in the Conceptual View, this transformation is embodied in the following subsection of the model:

RepositoryArchSpec

The problem with this architectural specification is that it isn’t very clear to both the Developers and Code Reviewers/Code Pairs what this means in terms of the constraints on the structure of the software - even if the team is familiar with Repositories and has read Evans. That’s not so say there’s no value in the architectural specification as it stands (there is definite value in communicating the architecture at a high level), it’s just that if the specification could be enhanced it would become an even greater point of leverage for the team.

This enhancement can be accomplished very easily using the UML concept of a Pattern (some additional info is available here). Rather than bore you with the all the UML standards goodness, I’ll just pull the depiction from the model of the “Repository Pattern”:

RepositoryPattern

As discussed in the Eden and Kazman article on the Intension/Locality Thesis, both architectural and design specifications concentrate on the definition of constraints on the structure of the software – they just differ on the scope of the constraints (the locality). The UML pattern specification above clearly illustrates this concept in the definition of the roles that constitute the pattern (e.g., “Repository Factory”) and constraints on those roles (e.g., “Only domain entities that are Aggregate Roots can have Repositories”).

What is particularly noteworthy in model above is that the pattern roles define a further constraint in terms of the use of a standard code interface (“IRepository<T>”). We’ll see the implication of this below.

As I discussed in Part 1, notice how this pattern does not specify to a Developer on the team which exact Aggregates, Aggregate Roots, and Repositories need to be built (e.g., Contracts, Customers, Orders, etc) – it only specifies only how these items should be built.

While this enhancement of the Repository architectural specification provides powerful leverage to the team, UML has one last enhancement to increase the power of Agile Software Architecture. The following model illustrates a hypothetical example of software that is in compliance with the Repository architectural specification:

RepositoryPatternExample

As I described in Part 1, I would argue this model exemplifies the difference between Architecture and Design in an Agile project. I would also argue that the model above illustrates the differences between the Architect and Developer roles on an Agile project. Specifically, the model above illustrates that the Agile Architect is responsible for the definition of the architectural constraints of the software (Repository in this case). Additionally, the model illustrates that another role on the team identifies that a design is required for the concept of “Product” that complies with the architecture of the software – the Developer role on Agile projects.

NOTE – As I’ve wrote previously, the best Architects also craft software. As such, it is important to understand that Architects may bounce back and forth between the Architect and Developer roles on an Agile project – defining architectural specifications one day and delivery software in compliance with the architecture the next.

A second, more complex, example will hopefully cement these ideas.

 

WCF Service Architectural Specification

The Conceptual View of the software architecture identifies the usage of the “WCF Service Pattern” as an architectural specification. Specifically, the following subsection of the Conceptual View defines this architectural specification:

WCFServiceArchSpec

As we saw previously with the Repository architectural specification, the WCF Service architectural specification has a UML pattern specification:

WCFServicePattern

While the WCF Service architectural specification is quite a bit more complicated than the Repository architectural specification, it is worthy to note that it again clearly segments Architecture from Design and segments the Architect from the Developer on an Agile project. Another thing that is worthy to note in the model above is the multiplicity constraint within the “WCF Operation Contract” role in the pattern. Specifically, this constraint specifies that every instance of the WCF Service architectural specification must have at least one instance of the “WCF Operation Contract” role, but there is no upper bound on the number of “WCF Operation Contracts”.

As with the Repository architectural specification, the WCF Service architectural specification also included an example instantiation of a design that is compliant with architectural spec. The model below illustrates this example design:

WCFServicePatternExample

There you have it! Some very powerful examples of how to leverage UML for Agile Architecture that is compliant with the Intension/Locality Thesis.

 

Reusable Code Assets

The above architectural specifications rely on some common reusable code assets as part of their constraints on the structure of the code. The following model illustrates the these assets from the UML model.

CoreClassesAndInterfaces

Don’t Fear UML & Software Architecture

Believe it or not, UML and Software Architecture are not antithetical to the use of Agile.

I’ve personally seen these tools and techniques succeed under both XP-like and Scrum-like (I use “-like” because I never seen a “pure” implementation – nor do I ever expect to ;-) methodologies. Typically architecture in these instances were a Sprint (or two 2-week XP iterations) at the start of the project, and then the architecture is iteratively addressed Agile-style throughout the project. Those of you who are in the know will recognize this as akin to some of the ideas behind RUP Elaboration.

I heartily advise giving this a try – your Developers will love you for it and it just might increase the fun you have as an Architect to boot!

Any feedback from Architects and Developers on this series would be greatly appreciated.

SkyDrive Files

The Formal Goodness of Agile Software Architecture – Part 1

The purely addictive aspects of working at The Big Show for a geek like me cannot be underestimated. In many ways Microsoft is like any other Fortune 500 company I’ve worked or consulted for, but I’m often reminded that working for Microsoft is different – it’s pure crack for geeks.

As an example, I recently attended a talk given by one of Microsoft’s Distinguished Engineers (DEs) on the subject of Software Architecture. One of the core tenets of this talk was the classification of what constitutes “Architecture” and what constitutes “Design”.

This is a subject I personally have found fascinating for a long time. In my years as an Architect I’ve had to explain the differences between these two highly abstract ideas on a number of occasions. Over time I became convinced that I had some really insightful, if not profound, explanations on the subject.

Later, when I was afforded the singular privilege of working with some very senior Developer talent (BTW, I define “senior Developer” based on knowledge and skill, not necessarily years of experience) in successfully developing software using Agile practices, I started to second-guess the wisdom of my explanations on what constitutes “Architecture” and “Design”.

Over the past few years I haven’t really had a satisfactory way of thinking about these concepts that mapped to my experiences doing Agile “the right way”.

It was during the course of the DE’s talk that I realized that this Architect may have found the “secret sauce” (to steal a term from Gabriel) I was looking for.

This particular DE strongly recommended an article where the authors (Eden and Kazman) formalize the distinction between “Architecture” and “Design”.

What I read was a simple and elegant way to classify what is “Architecture” and what is “Design”.

What I read explained the goodness that I’ve seen in building software in an Agile way.

What I read was pure, unadulterated crack…

 

Intension/Locality Thesis

In the article Eden and Kazman propose a formal basis for the distinction between the concepts of “Architecture”, “Design”, and “Implementation”. This distinction is formalized as the Intension/Locality Thesis:

  1. Architectural specifications are intensional and non-local;
  2. Design specifications are intensional but local;
  3. Implementation specifications are both extensional and local.

For the purposes of this post I’ll be ignoring the third point above, focusing instead on how the Intension/Locality Thesis applies to Agile Software Architecture. Before I can do this, I need to talk a bit about Intension and Locality.

NOTE – The rest of this post uses the term “specification” since the cited article uses this term extensively. However, I personally use this term very loosely. In my mind an Agile specification doesn’t necessarily entail a Word document or UML diagram. A whiteboard session with the Developers where certain decisions are reached (and maybe documented with digital photos), I would argue, also can constitute a specification in the context of this post.

 

What is Intension?

According to the dictionary the relevant definition is:

5. Logic. (of a term) the set of attributes belonging to all and only those things to which the given term is correctly applied; connotation; comprehension. Compare extension (def. 12).

Within the article, the authors further elaborate that specifications are intensional in nature if they define concepts in terms of constraints rather than relying on specific (or extensional) definitions.

For example, the specification “All source code will be written in a .NET language” is intensional in nature. This specification is intensional because it allows any programming language that is compliant with the constraint “a .NET language” (define that how you will ;-) to be used to author source code.

By way of comparison, the specification “All source code will be written in C# and/or VB.NET” is extensional in nature. The extensional constraint explicitly defines which programming languages can be used – C# and VB.NET.

Another way of thinking about intensional specifications is in terms of the number of ways that software can be structured to be in compliance with the specification – for intensional specifications the number of software structures that could be compliant with the spec is infinite (or a very, very large number).

 

What is Locality?

The article formalizes the idea of locality through the concept of subsumption. Essentially, a specification is considered local if every subsequent extension to the software is executed in a manner that complies with the initial specification. That is, every extension to the software subsumes the initial specification.

Since this is a little abstract, another way to think of specifications is that they are local if a subsection of the software satisfies the constraints of the specification without having an effect on the structure of the rest of the software.

By way of comparison, a non-local specification has an effect on the entire software structure – every nook and cranny. In terms of extension, this means that each and every change to the software must be in constant compliance with the original specification.

An example of a non-local specification is the requirement that all .NET classes must eventually have System.Object as a base class. In the case of .NET, this specification is so pervasive that the .NET compiler implicitly adds the System.Object inheritance even if the Developer doesn’t explicitly code it up. Any time you extend existing .NET software with a new class, the extension is always in compliance with this specification.

 

What is Design?

According to the Intension/Locality Thesis “Design” is simultaneously intensional and local. Based on the understandings of intension and locality described above, the following can be deduced about design specifications:

  1. Design provides a specification for software that can be fulfilled in an infinite number of ways.
  2. The constraints imposed by the Design specification are limited in scope – they do not affect every nook and cranny of the software’s structure.

Based on this meaning of Design, the article interestingly points out that the Gang of Four (GoF) arguably provides the quintessential set of Object-Oriented design specifications.

For example, the usage of the Strategy pattern within a set of C# code files fulfills the requirement of being intensional (the Strategy pattern can be coded in an infinite number of ways) and it is also limited in scope (the locality is the set of C# code files).

Additionally, subsequent extensions to the C# code can easily subsume the original design specification. For example, the addition of a Factory for the creation of Concrete Strategy instances to the code subsumes the original design specification. In turn, a further extension to the C# code to incorporate a Use Case Controller that uses the Factory and Strategies subsumes both design specifications, thereby continuing the “chain of locality” for the previous design specifications for the code.

 

What is Architecture?

Like Design, Architecture specifications must be intensional. However, Architecture is non-local – the constraints of Architecture specifications enforce compliance through every nook and cranny of the software’s structure.

The article cites the Law of Demeter as an example of an Architectural specification. From Wikipedia’s article, the Law of Demeter can be written as:

More formally, the Law of Demeter for functions requires that a method M of an object O may only invoke the methods of the following kinds of objects:

  1. O itself
  2. M’s parameters
  3. any objects created/instantiated within M
  4. O’s direct component objects

In reading the above definition it is clear that the Law of Demeter can be implemented in an infinite number of ways (it is intensional). What is also clear is that the Law of Demeter has an effect on every nook and cranny of the software’s structure (OK, this implicitly assumes using the OO paradigm, but you get the point ;-) – it literally dictates the way Developers engineer all of the software (it is non-local).

Another interesting way to think about the Law of Demeter is in terms of subsumption.

Take the hypothetical example of a piece of software that has been engineered in compliance with the Law of Demeter. If this piece of software is extended at a later point in time in a way that isn’t compliant with the Law of Demeter, but doesn’t alter the original structure, then we have the following situation:

  • The new software structure subsumes the original specification
  • The new software structure violates the architecture specification of the Law of Demeter.

Thinking about subsumption gives another way of defining whether a specification is architectural – can extensions to a compliant software structure subsume the original specification and then subsequently violate the original specification? If the answer is yes, then the specification is Architecture, not Design.

The article cites a number of classic examples of architecture specifications that are widespread in the industry, namely Pipes and Filters and Layered Architecture.

 

Agile Software Architectures

What I find so compelling about the concepts described above is that they explain the successes I’ve experienced firsthand in Agile projects. The tools, techniques, and practices that organically grew out of my working with the Developers on these projects can all be easily equated to the Intension/Locality Thesis – we just didn’t know that there was formal goodness that explained why we were successful.

Specifically, I would argue that the Intension/Locality Thesis explains the following in terms of Agile development:

  • What constitutes the Architecture of the software (or the “Metaphor” if you’re into XP)
  • What constitutes the Design of the software
  • What is the purview and concerns of the Architect
  • What is the purview and concerns of the Developer
  • What is the purview and concerns of the Code Reviewer/Code Pair

The first two bullet points are now old hat given the Intension/Locality Thesis, but interpreting the remaining three bullet points in terms of the Thesis and Agile is particularly interesting.

 

The Agile Architect

My experience has been that the Intension/Locality Thesis underlies the ability of an Architect to be agile by formalizing the mechanisms by which the Agile Architect leads through leverage. In terms of the Thesis, this usually takes on two primary forms:

  • The identification of those architectural specifications that most fit the problem space the software is attempting to address. Examples of these architectural specifications include:
    • Layered Architecture
    • Pipes and Filters
    • Law of Demeter
    • Unit test code coverage metrics (e.g., all Use Case Controllers shall have 80+% coverage)
    • Coding standards (e.g., no direct access to class member variables)
  • The identification of design specifications as constraints on the software structure. These identifications transform the design specifications to architectural specifications by making them non-local in nature. Examples of these identifications include:
    • All UI Layer code shall be written using the Model-View Presenter (MVP) pattern
    • All MVP Presenters shall rely on a WCF Service Layer as the Model
    • All WCF services shall delegate implementation to Use Case Controllers
    • The Application Layer Domain Model shall be built as DDD Aggregates
    • All Data Store access shall be implemented using DDD Repositories

You’ll notice a large emphasis on the usage of “off the shelf” architectural and design specifications above (aka Patterns). This is, IMHO, nothing more than the natural manifestation of leverage that organically occurs within successful Agile projects – the result of the need for real-time, high-bandwidth communication between team members. My experience has been that teams inevitably come up with a vocabulary to facilitate high-bandwidth communication. As such, it only makes sense to me not to have to reinvent the wheel every time.

 

The Agile Developer

The Intension/Locality Thesis again provides an elegant formalization for thinking about the role of the Developer on an Agile project. In terms of the Thesis, the Agile Developer is primarily responsible for one thing – engineering software that complies with the architectural specifications.

Now we all know that Agile Developers are responsible for far more than this. For example, Developers are responsible for executing the Agile practices of the team (e.g., CI, Pair Programming, Daily Scrums, etc), but it is interesting to note that on an Agile team the actual engineering constraints are actually pretty light.

However, my experience has been that the best Developers (not to mention the only Developers I would want to work with on an Agile project) self-enforce another engineering constraint on the software – they extensively leverage “off the shelf” design specifications (aka Patterns) in their code.

As an example, take the following hypothetical scenario. A Developer is working on a project where an architectural specification is “All WCF services shall delegate implementation to Use Case Controllers”. As part of the Developer’s Use Case Controller implementation the developer elects to employ the Visitor pattern to apply validation logic on incoming messages to the Controller.

Notice that the Agile Developer doesn’t run her Visitor-based design by the Architect or Dev Lead – they just implement it. No design docs, no design reviews, just the essence of Agile – the creation of quality software by empowered team members.

 

The Agile Code Reviewer/Code Pair

Again, the Intention/Locality Thesis provides excellence guidance as to the activities and concerns of the Agile Code Reviewer (or Code Pair). In line with the Thesis, the Code Reviewer is primarily concerned with the monitoring of, coaching on, and enforcement of the architectural specification constraints within the software.

I would argue that this is a critical idea that often gets lost. If everyone is spending inordinate amounts of time preparing for, conducting, and remediating Code Reviews how Agile can your team actually be? If a team legitimately needs this level of “quality control” then I would argue that the team has likely picked the wrong delivery methodology based on the risk profile of the project (which, BTW, may include the risk that the Developers are not senior enough to do Agile).

I would also add that the best Agile teams have Code Reviewers that naturally taken on a secondary review concern for the identification of any “code smells” within the software. Typically, these code smells tend to take on one of three primary forms:

  • The Developer could benefit from the application of one or more Patterns (design specifications)
  • The Developer applied a Pattern in a suboptimal/non-intuitive way
  • The Developer applied too many Patterns

As I’ve written about previously, the use of Code Reviewers should really be about creating leverage through the federation of architectural stewardship. What the Identity/Locality Thesis gives us is a formal and elegant way to classify exactly what “architectural stewardship” means.

 

Next Time

The Identity/Locality Thesis has got me pretty hopped up right now. As such, I’ve taken a short break from writing about System.Identity and M.

For my next post I’m going to wrap up my thoughts on the Thesis by exploring one last concept – how an Agile Software Architecture can be effectively modeled in UML for easy consumption by the team.

Stay Tuned!

Oslo “M” Graphs and Inheritance

In my last post I explored the subject of applying Object-Relational Mapping (ORM) concept to modeling in M. What I discovered was that M handles ORM pretty well and allows for the modeling of polymorphic inheritance within M metamodels – thereby enabling rich Object-Oriented runtimes to consume Oslo metamodels.

At the end of the post I briefly discussed the question of which of the two ORM patterns discussed in the post was best – at which point I quickly punted on the question.

My reasoning for punting was that a final accounting would need to wait until I explored the M graph implications of each of the ORM patterns.

This post will be that final accounting.

 

Table per Class Hierarchy Graphs

In the ORM post I first took a look at using a single M type to create an extent that would model an entire class hierarchy in the SQL Server Repository. This is ORM pattern has been an effective design for relatively simple class hierarchies where the classes don’t change much. For reference, here’s the M for the types and extents covered in the post:

   1: type Department
   2: {
   3:     Id: Integer64 => AutoNumber();
   4:     Folder: Integer32 => 100;
   5:     Name: Text#64;
   6: } where identity Id;
   7:  
   8:  
   9: type Person
  10: {
  11:     Id: Integer64 => AutoNumber();
  12:     Folder: Integer32 => 100;
  13:     Discriminator: Text where value in {"Person","Manager","IndividualContributor"};
  14:     FirstName: Text#32;
  15:     LastName: Text#32;
  16:     Department: Department? where value in Departments;
  17:     JobTitle: Text#32?;
  18:     Manager: Person? where value in People;
  19: } where identity Id;
  20:  
  21:  
  22: // Extent definitions
  23: Departments: Department*;
  24: People: Person*;

In terms of M graphs to instantiate the model, the code is really straightforward:

   1: // M graphs
   2: Departments
   3: {
   4:     Department1 { Name => "Department#1" },
   5:     Department2 { Name => "Department#2" }
   6: }
   7:  
   8: People
   9: {
  10:     JohnDoe { FirstName => "John", LastName => "Doe", Discriminator => "Person"  },
  11:     JoeManager { FirstName => "Joe", LastName => "Manager", Discriminator => "Manager", Department => Departments.Department1, JobTitle => "Manager", Manager => People.SteveDirector },
  12:     SteveDirector { FirstName => "Steve", LastName => "Director", Discriminator => "Manager", Department => Departments.Department1, JobTitle => "Director" },
  13:     FredWorker { FirstName => "Fred", LastName => "Worker", Discriminator => "IndividualContributor", Department => Departments.Department1, JobTitle => "Manager", Manager => People.JoeManager }
  14: }

As we can see from the code above, instantiating Person instances in the model is just a matter of providing the correct data based on the type being instantiated (as defined by the Discriminator field).

What I found pretty cool is that Intellipad actually gives you Intellisense when you’re authoring M graphs. This was very handy when referencing items in other collections. Here’s a screenshot illustrating the coolness:

MGraphIntellisense

Table per Concrete Class Graphs

The second ORM pattern relies on a M type and an extent for each concrete class in the hierarchy. Within the Oslo Repository this ORM pattern manifests as a collection of SQL Server tables where the tables representing derived classes (Manager and IndividualContributor) have Primary Keys (PKs) that are Foreign Keys (FKs) to the table representing the Person class. In using this ORM pattern, a join is required to the People table whenever a Manager or IndividualContributor is retrieved from the SQL Server Repository.

Here’s the M code for the ORM pattern:

   1: type Department
   2: {
   3:     Id: Integer64 => AutoNumber();
   4:     Folder: Integer32 => 100;
   5:     Name: Text#64;
   6: } where identity Id;
   7:  
   8: type Person
   9: {
  10:     Id: Integer64 => AutoNumber();
  11:     Folder: Integer32 => 100;
  12:     FirstName: Text#32;
  13:     LastName: Text#32;
  14:     Discriminator: Text where value in {"Person","Manager","IndividualContributor"};
  15: } where identity Id;
  16:  
  17:  
  18: type Employee
  19: {
  20:     Person: Person where value in People;
  21:     EmployeeId: Integer16;
  22:     Department: Department where value in Departments;
  23:     JobTitle: Text#32;
  24:     
  25: } where identity Person;
  26:  
  27:  
  28: type Manager : Employee
  29: {
  30:     Manager: Manager? where value in Managers;
  31: } where value.Manager.Person.Discriminator == "Manager";
  32:  
  33:  
  34: type IndividualContributor : Employee
  35: {
  36:     Manager: Manager where value in Managers;
  37: } where value.Manager.Person.Discriminator == "Manager";
  38:  
  39:  
  40: // Extent definitions
  41: Departments: Department*;
  42: People: Person*;
  43: Managers: Manager*;
  44: IndividualContributors: IndividualContributor*;

And the M graphs to instantiate the model:

   1: // M graphs
   2: Departments
   3: {
   4:     Department1 { Name => "Department1" }
   5: }
   6:  
   7: People
   8: {
   9:     JaneDoe { FirstName => "Jane", LastName => "Doe", Discriminator => "Person" }
  10: }
  11:  
  12: Managers
  13: {
  14:     SteveDirector { Person => { FirstName => "Steve", LastName => "Director", Discriminator => "Manager" }, EmployeeId => 1234, Department => Departments.Department1, JobTitle => "Director" },
  15:     JoeManager { Person => { FirstName => "Joe", LastName => "Manager", Discriminator => "Manager" }, EmployeeId => 4321, Department => Departments.Department1, JobTitle => "Manager", Manager => Managers.SteveDirector }
  16: }
  17:  
  18: IndividualContributors
  19: {
  20:     FredWorker { Person => { FirstName => "Fred", LastName => "Worker", Discriminator => "IndividualContributor" }, EmployeeId =>1122, Department => Departments.Department1, JobTitle => "Worker", Manager => Managers.JoeManager }
  21: }
</