MEF is not An IoC container; but MEF uses IoC

Somehow I got on the conversion of MEF while chatting with Glenn Block.  IoC came up in that conversion.  I believe, at some point, I said something along the lines of MEF is not an IoC container; but MEF uses IoC.  Someone else asked me to clarify that after the conversation.  It’s a common misconception that MEF *is an* IoC container.  I thought it might be useful to summarize those conversations for others.

Part of what gives MEF the ability to do what it does is most certainly IoC.  Traditional dependencies (control) are inverted so that something (the host) doesn’t depend on a concretion (the extension, in the case of MEF) but an abstraction.  The abstraction with MEF and IoC is an interface.

MEF manages extensions—dependencies—that may or may not exist at run-time but are rarely known/exist at compile-time.  This needs to occur because you want 3rd parties to extend your application (of course, conceivably you must produce and publish your application before a 3rd party can even conceive of extending it).  For any one dependency, MEF may be managing multiple extensions.

The difference with an IoC container is that it’s managing static dependencies: dependencies that must exist at compile-time in order for the application to correctly run at run-time.  The impetus of IoC is different than MEF in that you don’t want to offer the ability to “extend” your application, but ensure that a particular class doesn’t have a direct coupling (or dependency) on another class.  IoC doesn’t remove the dependency entirely, it just means the code can evolve independently.  For the application to run correctly when deployed, it depends on ClassA being injected into ClassB at some point for that to happen.  But, ClassA can compile without ClassB.  This is always a one-to-one dependency.

If MEF were truly an IoC container then you’d expect be able to use an IoC container to extend an application at runtime—which is not the case.

Women in High Tech

I know a lot of really good people in software development from around the world.  I’m fortunate to have spent face-to-face time with many of these people.  These people bring great value to our industry.

One thing that was apparent again at the MVP Summit is the heavy male attendance on the software development side.

The point was made a couple of times and some tweets flowed about it a few times.  Is it a good-old-boy’s network?  Are software development leaders dominated by the “Alpha Male”.  Are women simply not willing to put up with any of us?  I personally don’t know.

What I do know is that, as a community, we’re not better off for it.  Women bring a sense of communication that is lacking by many men in the software development industry.  MVPs are generally exceptional in this respect; but they’re not immune.

I have a couple of challenges of my readers.  I challenge my readers to foster and mentor more women in software development.  I also challenge my readers to help point out women in software that should be

If you know a woman in high-tech that you believe should be recognized just as much as any “Alpha Male”; please point them out.  Use this blog if you like, or call them out on your own blog—detail why you think they’re leaders in our industry and deserve recognition.

kick it on DotNetKicks.com

What is Data-Driven Design

Data-Driven Design is a process of designing software structure and functionality.  Data-Driven Design infers functionality mainly from the information that the software is meant to maintain.  The functionality of the system focuses on having to create, view, and update that information.

Data-Driven Design is useful for designing data models and designing database schemas.  The definition of data and the structure of a database is solely focused on the data it models or contains.

Data-Driven Design differs in focus from Structured Design, which focuses mainly on what logic needs to be performed by defined how the logic changes program state.

Posted by PeterRitchie | with no comments

Nourishing Technology and product communities.

Software technology and products have had a fairly unique attribute until recently: communities.  Software technologies and products have had this seemingly innate ability to have a group of people rally together about the product.  This community is a positive thing for the product: it provides technical (an sometimes emotional) support for the product and promotes and evangelizes the product.

With the maturity of online social “platforms”, many non-software products are trying to build their own communities to reap the benefits that software product communities have gains for so many years.  This trend simply validates the importance of product communities.

So, how can a company nourish and maximize the benefits of a product community?

First of all, we’ve touched on some of the benefits of these communities; let’s detail some other benefits:

  • Free technical support personnel—users helping users
  • Free promotion—comfort of real-world users to potential customers
  • Highly focused and vetted feedback—users-helping-users point out documentation/usability short-comings
  • Free Quality Control—users-helping-users point out flaws and workarounds.
  • Product developers feel empowered and more like contributors.

Some of the side-effects of the benefits include:

  • Increase sales
  • Reduced support costs
  • Increased quality
  • High ROI for product development because it’s more focused to user need.
  • Reduced product development costs.
  • Improved employee morale.

Clearly an established community  is positive to the bottom line.

Knowing what some of the benefits are, we can focus efforts on maximizing those benefits.  Without some way for a community to gather and communicate there’s no way for the community to provide any sort of support for fellow members.  The ability to community members to gather provides the ability for the community to openly discuss the benefits of the product and the different ways to use the product to solve problems.  This positive community communication promotes the product by providing potential customers with real-world solutions to their existing problems and details how to use the product to realize those solutions.  A positive community also puts a human face onto the product and company that potential customers can associate with.  Recognizing community leaders categorizes and prioritizes users and their communications.  Community communication provides tangible feedback about the product and company that can be mined at any time and vetted by category.  Employee involvement means the company is more personal and provides employees with a sense of belonging and empowerment because they see the human factor of their work.  Employee work into the product is of higher quality because employees see the human impact of what they are working on and have a sense of belonging.

Nourishing Community Guidelines

  • Community is not a replacement for technical support.
  • Provide an identity for your community.
  • Provide an presence for your community.
  • Provide top-notch technical support.
  • Be open about the future.
  • Provide a positive feedback collection mechanism.
  • Organize, prioritize, and cultivate feedback.
  • Treat your community efforts as a product.  They need technical support, to be user-focused, high-quality, reliable, robust, easy-to-use, and provide a positive experience.
  • Provide recognition for community super-stars.
  • Rapidly improve product to promote positive community communication.
  • Employees should be tasked with and regularly communicate with the community.

kick it on DotNetKicks.com

Posted by PeterRitchie | with no comments

The weather outside is frightful

With news and Twitter reports of snow coming to the mid and eastern parts of North America, I’m reminded of when my family moved (temporarily) from Canada to St. Louis Mo. (okay, really a suburb of St. Louis).

St. Louis is a Midwestern city in the United States.  As such, it gets a “different” amount of snow than we were used to.  Sure enough, the first few months we were there it snowed.  Nothing major in our books.  About 6 inches, if memory serves.

Well, if our neighbours hadn’t thought this was some sort of natural disaster!  At the time, St. Louis (or at least he municipality we were in) didn’t have snow ploughs.  Well, as you can imagine, if there’s no way to get rid of 6 inches of snow (and no one really gets winter tires) everyone was at a standstill.  As I recall, we still had snow tires on our Cutlass Sierra; so, we proceeded to drive around to do whatever we needed to do.  Going to the grocery store was a bit of a waste of time because the shelves were bare.  With news of several inches of snow, everyone bought whatever they could get.

We took it in stride and strapped on our cross-country skies and skied around the neighbourhood.  I found out later that people were looking at us out their windows wondering why these crazy people were outside risking their lives!

Of course, schools were closed and businesses were shut down until the snow could be removed.  I think it was a full two weeks before they procured some ploughs to stick on the front of garbage trucks to motor around the roads getting snow off them.  We had to spend an extra 20 minutes a day in class to make up for the lost time at school.

Returning to Canada (Ottawa), I can only remember once when schools were closed due to the cold weather.  And it was due to the temperature being –40 C.  I can’t begin to count how many times we’ve received over a foot of snow, simply shovelled/ploughed it out of the way and gone on with life.

Anyway, good luck to those areas of North America that can’t handle a significant amount of snow.  Believe me, it’s survivable.

The Difference between an Anti-Pattern and a Code Smell

I think the term “Anti-Pattern” is being over used.  There’s various definitions for Anti-Pattern like “obvious but wrong, solutions to recurring problems” and “common approaches to solving recurring problems that prove to be ineffective”.  All definitions have a common thread: they’re recognizable solutions (pattern) that don’t work in at least one way and should never be used.

This means that anything that does work, when used correctly, isn’t an Anti-Pattern.  Transitively, that doesn’t make incorrectly used Patterns Anti-Patterns.

Code Smells, on the other hand, are defined as “…a hint that something might be wrong, not a certainty.”.

I’ve seen the term Anti-Pattern used in a couple of places lately that describe scenarios where patterns are used incorrectly.  Each and every pattern has a time and a place (a context).  Outside of that context, it is not an anti-pattern.

The term Code Smell is much better to describe inappropriate uses of patterns.

For example, Mark Seemann recently blogged that Service Locator is an Anti-Pattern.  I disagree.  I argue that there is a time and a place for Service Locator.  Incorrect use of Service Locator is definitely a code smell—it’s an indication (a hint, not a certainty) that there’s something wrong with the design.  The fact that you’re using Service Locator instead of Dependency Injection is, indeed, a design issue.  But, dependency injection may not be possible.  WebForms, for example.  I can’t inject dependencies into a web form because I have no control over it’s construction.  I’m forced to either use a Service Locator or a Factory to aid in my decoupling efforts.

 

 

kick it on DotNetKicks.com

DevTeach 2010 Toronto

DevTeach 2010 Toronto has been announced with a great session line-up.  This DevTeach turns out to be a fantastic deal because you not only get your usual DevTeah goodness (to attend the sessions, hob-nob with the speakers, etc.) but you also get a free copy of Visual Studio Professional with a 1 year MSDN Premium license.  That's a US$2499 value alone; for the price of admission.

If you register before Jan 1 2010, admission is US$664 (30% off!); before Jan 30 2010, it's US$759; after Feb 1 2010, it's US$854; and after Mar 1 2010, it's regular price (US$949).  So, the sooner you register the better the deal is.

If you're from out of town, if you book your accommodation before Feb 8 2010 you can save CA$50 off the daily rate of $189 at Delta Meadowvale.

I highly recommend DevTeach, the speakers are top notch.

This year I've finally found time in my schedule to give two sessions.  I'll be doing "Being an Agile Consultant" and "Advanced Refactoring with Visual Studio 2010".

I hope to see you there.

Posted by PeterRitchie | with no comments

TechDays Canada 2009 Developer Foundations Call For Speakers

We need speakers for Vancouver and Toronto for the Developer Foundations track for TechDays Canada 2009.

We’re finalizing the abstracts right now; but, it looks like there will be four sessions in this track.

SOLID : the five OO principles that will change your life forever.

  • Will cover Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion.  What they are, how to use them, examples, etc.

Refactoring for Fun and Profit

  • How to improve your existing code and architecture through refactoring and avoid “another re-write”.

Advanced .NET (C# and VB)

  • Advanced generics, lambdas and anonymous methods, LINQ to Objects, Error/Exception handling and throwing, etc.

Layers, the secret language of architects

  • Detailed domain layering.  Domain-Driven design will come into play with this session.

Vancouver is September 14-15, and Toronto is September 29-30.

If you’re interested you can email me (see the Contact link on the left, if you don’t already have my email) or Justice Gray or send us a tweet (@PeterRichie and @JusticeGray) and we’ll try to get more information to you as it is available.

Why Fundamentals are Important to Microsoft’s Bottom-line

Justice Gray recently blogged about his concern of lack of SOLID coverage at TechDays despite how Joey Devilla blogged about SOLID principles (and then went on to say that “Maaaaaaaaaaaaaaaaaaaaaaaaaaybe” SOLID would be covered in the TechDays Canada tracks this year).  Joey Devilla retorted with an open letter.

Justice’s concerns are well founded; TechDays is a “showcase current Microsoft tools and technologies” and that’s primarily what it does.  Most sessions cover how to use Microsoft tools and technologies.  But, most sessions don’t do it in a way that exemplifies what many consider fundamentals.  Most sessions cover using Microsoft technologies procedurally.

What is really missing from TechDays sessions is how to use these technologies beyond the syntax and beyond procedurally and how to use them and how to design and architecture the rest of your application or system with generally accepted fundamentals.

So, why?  Why shouldn’t Microsoft simply sell its wares?

Attendees to TechDays aren’t writing software that simply uses a single Microsoft technology, they’re writing systems and applications where that technology may be but a single part of the entire system.  That system also needs to be based on generally accepted design and architecture principles and newcomers to a technology also need to know how to integrate that into systems such as this.  Coming away from a “demo” session where none of the demo code is useable in a software shop that *does* follow SOLID doesn’t add much value to the attendee.

A community who knows only how to use a technology based on demo code doesn’t produce robust and easy to maintain software.  Worse case, this leads to a community known for poorly written, low-quality, hard-to-maintain, slow-to-market software.  This drives people away from the technology into the arms of other technologies.  I’m sure many people can think of at least one Microsoft-based technology not well viewed by the industry.

A community that takes a leadership role in producing quality software inadvertently sells the technology it uses.  It’s easier for new people to join the community and get productive sooner.  This has a snowball effect as the community grows.  This is nothing but positive to the bottom-line.

Microsoft-technology-based communities already have a reputation for cowboy coding and lack of good fundamentals.

What TechDays needs more of is how to properly use Microsoft platforms like Visual Basic and C# and how to integrate other technologies into those platforms using generally accepted fundamentals.  Simply knowing the syntax of a technology doesn’t mean you know how to integrated into the rest of your system.

kick it on DotNetKicks.com

Unit testing WCF data contract serialization.

WCF service define "data contracts" for their interfaces.  These contracts are often defined in an XML schema document and used to generated WCF data contract code.  This process effectively creates a .NET type that will serialize to a chunk of XML text.

Depending on the operation of the WCF service, its code may be responsible for creating some of these objects.  A return value from an operation, for example.  While the framework handles XML serialization of these object behind the scenes.  But, if your have complex types and you end up not setting all the properties correctly in your object tracking down what properties haven't been set properly can be a chore as the server would have to enable passing exceptions back to the client, etc.

A technique that I've found useful is to add unit tests to ensure the creation of my contract objects are indeed serializable.

For example, I may have an method GetCustomer that retrieves a customer.  Where I would like to create this contract Customer I would create a method to create this contract object based on parameters, like a Model Customer object.

For example:

    PRI.ExampleWcfService.Customer ToWcfContractCustomer(PRI.Model.Customer customer)

    {

        //...

    }

Now, one of the unit tests would call this method and attempt to serialize the object to XML text, for example:

    [Test]

    public void WhenCreatingCustomerContract_EnsureXmlSerializationSucceeds()

    {

        PRI.ExampleWcfService.Model.Customer customer = CustomerRepository.Get(1);

        PRI.ExampleWcfService.Application.Customer contractCustomer = ToWcfContractCustomer(customer);

        String text = Utility.ContractObjectToXml(contractCustomer);

    }

where Utility.ContractObjectToXml is declared as:

    public static class Utility

    {

        public static string ContractObjectToXml<T>(T obj)

        {

            DataContractSerializer dataContractSerializer = new DataContractSerializer(obj.GetType());

 

            String text;

            using (MemoryStream memoryStream = new MemoryStream())

            {

                dataContractSerializer.WriteObject(memoryStream, obj);

                byte[] data = new byte[memoryStream.Length];

                Array.Copy(memoryStream.GetBuffer(), data, data.Length);

 

                text = Encoding.UTF8.GetString(data);

            }

            return text;

        }

    }

Now, when this unit test is run, it will fail if the serialization process throws an exception because the resulting XML would violate the schema.

See [DataContractSerializer.ReadObject is easily confused] for why I'm creating a new buffer and copying the serialized data before converting it to a string.

Digg ThisDotNetKick This
Posted by PeterRitchie | 1 comment(s)
Filed under: ,

DataContractSerializer.ReadObject is easily confused.

With WCF services you need to declare contracts and generate contract classes that encapsulate those contracts.  Most of the time you can simply let the framework deal with whatever it needs to do to deal with these objects.  Sometimes, you need to actually see without running a service what XML would result from a contract object or serialize a contract object from XML text.

In .NET 3.5 there exists the System.Runtime.Serialization.DataContractSerializer class that perform serialization of data contracts.

Based on its documentation it seems fairly simple to create data contract object to/from XML methods.  For example:

    public static T XmlToContractObject<T>(string xml) where T : class, IExtensibleDataObject

    {

        MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(xml));

        using (

        XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.Unicode,

                   new XmlDictionaryReaderQuotas(), null))

        {

            DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(T));

            return dataContractSerializer.ReadObject(reader) as T;

        }

    }

 

    public static string ContractObjectToXml<T>(T obj) where T : IExtensibleDataObject

    {

        DataContractSerializer dataContractSerializer = new DataContractSerializer(obj.GetType());

 

        String text;

        using (MemoryStream memoryStream = new MemoryStream())

        {

            dataContractSerializer.WriteObject(memoryStream, obj);

 

            text = Encoding.UTF8.GetString(memoryStream.GetBuffer());

        }

        return text;

    }

But, when you try to perform a round-trip from a contract object to XML and back you'll notice that you get SerializationException with the cryptic message of "There was an error deserializing the object of type <sometype>.  The data at the root level is invalid", despite that the XML seems view when examined.

When Encoding.UTF8.GetString is called, it literally translates the entire array into a String object.  This means that it reads any and all 0 bytes in the array and dumps out null characters ('\0') into the string.  Why do I mention this?  Well, MemoryStream uses a self-expanding buffer to write to.  When MemoryStream runs out of space in its buffer, it doubles the size of the buffer, zeroes it out, then copies the original buffer to the start of the new buffer.  When MemoryStream.GetBuffer is called it simply gets a reference to this buffer, regardless of how many bytes have been written to the stream.  So, most of the time you get a buffer with zeroes padded to the end of it.

If you look closely at the resulting XML, there are a bunch of '\0' characters at the end of the string.

As it turns out, DataContractSerializer.ReadObject (or something it calls) doesn't like all the extra null characters and this is the cause of the SerializationException.

Irritating as this may be, the fix is fairly straightforward.  Simply, create a new buffer equal to the length of the stream and copy the data from the MemoryStream buffer to the new one--trimming all the extra zeroes.  For example:

    public static string ContractObjectToXml<T>(T obj) where T : IExtensibleDataObject

    {

        DataContractSerializer dataContractSerializer = new DataContractSerializer(obj.GetType());

 

        String text;

        using (MemoryStream memoryStream = new MemoryStream())

        {

            dataContractSerializer.WriteObject(memoryStream, obj);

            byte[] data = new byte[memoryStream.Length];

            Array.Copy(memoryStream.GetBuffer(), data, data.Length);

 

            text = Encoding.UTF8.GetString(data);

        }

        return text;

    }

Digg ThisDotNetKick This
Posted by PeterRitchie | 3 comment(s)
Filed under: , ,

Evolving code over time

Given economics, time constraints, resource limitations, etc.; you can't write all the functionality for a given solution for a single release.  Even if you weren't limited by these constraints, you're likely to get changing requirements as development progresses and everyone learns more about the software under development.

It's fairly easy to prioritize what is developed and what isn't.  You simply develop only what you need (see YAGNI).  But, how do you manage adding new functionality without causing undue grief?  One way is to only make additive changes to the code.  For example, let's say we have the method create CreateRequestPacket that creates a blob of bytes to send to a host over the wire:

public static byte[] CreateRequestPacket()
{
    byte[] result = new byte[12];
    result[0] = REQUEST_CODE;
    result[1] = NO_OPTIONAL_DATA_FLAG;
    result[2] = (byte) (result.Length - 2);

    Random random = new Random();
    for(int i = 3; i < result.Length; ++i)
    {
        result = (byte) (random.Next() % byte.MaxValue);
    }
    return result;
}

 

 

In iteration x it writes out a request making certain assumptions about what the request contains.  But, in iteration y it needs to optionally include other data.  A non additive way is to simply modify CreateRequestPacket to do what is needed:

public static byte[] CreateRequestPacket(bool useOptionalData)
{
    byte[] result = new byte[12];
    result[0] = REQUEST_CODE;
    result[1] = OPTIONAL_DATA_FLAG;
    int index = 2;
    if(useOptionalData)
    {
        result[index] = GetOptionalData();
        ++index;
    }
    result[index] = (byte) (result.Length - index);

    Random random = new Random();
    for(int i = index + 1; i < result.Length; ++i)
    {
        result = (byte) (random.Next() % byte.MaxValue);
    }
    return result;
}

Now all calls to CreateRequestPacket need to change before a build can occure and you might not be able to modify all the files that contain these calls.  So it causes undue blocking and forces you to change a number of files before you can check the file that CreateRequestPacket is contained withing.

Another way of implementing this would be to implement an additive change.  That is, add a method that does what is needed and change the previous implementation to call the new method.  For example:

public static byte[] CreateRequestPacket(bool useOptionalData)
{
    byte[] result = new byte[12];
    result[0] = REQUEST_CODE;
    result[1] = OPTIONAL_DATA_FLAG;
    int index = 2;
    if(useOptionalData)
    {
        result[index] = GetOptionalData();
        ++index;
    }
    result[index] = (byte) (result.Length - index);

    Random random = new Random();
    for(int i = index + 1; i < result.Length; ++i)
    {
        result = (byte) (random.Next() % byte.MaxValue);
    }
    return result;
}

public static byte[] CreateRequestPacket()
{
    return CreateRequestPacket(false);
}

This allows you to check the file that contains CreateRequestPacket in right after passing unit testing and allows you to gradually change all calls to CreateRequestPacket as time permits.

Digg ThisDotNetKick This

DevTeach 2009 Vancouver

The schedule for DevTeach 2009 Vancouver has been announced (http://www.devteach.com/).  There’s lots of great software development sessions from some of the leaders in our industry.

If you’re planning on improving yourself, this is the conference to go to.  Not only can you attend excellent sessions; but you can hob-knob with the presenters and pick their brains.

If you have a friend or co-worker who’s interested, there’s a limited-time two-for-one offer for an even better price: http://www.devteach.com/Register.aspx

kick it on DotNetKicks.com

Developing with Source Code Control - Best Practices Part 2

[Edited 14-Mar-09: clarified generated code SCC practice]

This edition provides SCC vocabulary and some more practices that make development life easier.

Vocabulary
Trunk
The root of the project or database.  Sometimes called mainline or baseline; depending on the SCC structure, this is where most of the development occurs.
Mainline
The root of the project or database.  Sometimes called trunk or baseline; depending on the SCC structure, this is where most of the development occurs.
Baseline
The root of the project or database.  Sometimes called mainline or trunk; depending on the SCC structure, this is where most of the development occurs.
Tag
A snapshot in time of the system or a project/subfolder in the system.  Usually also associated with an annotation explaining the significance of that point of time.  Also known as label.
Label
A snapshot in time of the system or a project/subfolder in the system.  Usually also associated with an annotation explaining the significance of that point of time.  Also known as tag.
Branch
A "copy" of subfolders and files that are controlled separately from the trunk with an intention to eventually merge back into the trunk.
Merge
Unifies two independant changes into one.  Often the process of merging requires manual resolution of conflicts.
Merge Conflict
When two independant changes cannot be automatically merged.
Commit
Same as check in
Check in
When changes are written to the repository.
Head
The most recent version of code in the system.
Fork
For the most part, same as branch--depending on the SCC system.  More fun to use than branch, "I forked the code".
Copy-modify-merge
Under this SCC model the SCC always merges changes back into the database (trunk or branch, depending on what you're editing). This model assumes a team model where there is the likely posibility of more than one person working on the same file at the same time.  This model rarely precludes the ability to lock a file before modification if changes to the file cannot be merged).  This is the preferred SCC model.
Lock-modify-unlock
Under this SCC model the SCC forces devs to lock files they wish to edit before modifying them.  (with IDE integration this is often transparent).
ALM
Application lifecycle management.

Practices
Don't use Visual SourceSafe for your SCC system.
Believe me, I've been there and have the scars to prove it.  Visual SourceSafe (VSS) has a unique process that isn't mirrored by many major contemporary SCC systems.  VSS is a distributed file-based SCC system and as such is prone to data corruption--not really something that is acceptable in any sort of "Control" system.  Branching is really difficult in VSS.  If you're one person and you have your VSS database on the same computer; you're likely fine.  Otherwise, do yourself a huge favour and consider another SCC system, like Subversion (it's free).  VSS doesn't scale well; as time goes on and the database increases in size, developers are added to the project, VSS gets slower and slower.

Don't put generated  code in SCC
SCC provides the ability to rollback to a state in the past that allows compilation of the solution.  Code that is generated [edit start] as part of the/a build process [edit end] can be generated at any time; there's no need to put that code into SCC.  With lock-modify-unlock SCC systems, generated code that is checked-in will be locked and cause errors during build unless you lock it on every build.  This will cause conflicts in lock-modify-unlock systems in that you end up not being able to build while somone else is building (yes, you likely build serveral times a day).

Make sure unit tests pass before checking in.
This means *all* unit tests.  If you check in a change that causes a unit test to fail, someone else won't know where to start to make that unit test pass.  You're wasting your time and setting the project schedule back by not ensuring unit tests pass before checking in changes.  If your team allows it, use some sort of continuous integration suite.  This allows you to get feedback upon every check-in that tells you whether all the unit tests pass.  If you have an SCC or ALM that supports it, enable guards that force the unit tests to pass before changes are allowed into SCC.

Work on one set of related changes at a time.
It's more efficient to work on one thing at a time.  Switching back and forth from task to task means wasting time getting into a different frame of mind and sometimes a different configuration.  This also causes issues with SCC in that you've now got modified files that you're not currently working on.  The longer they're kept unmerged, the more likely there will be issues during merge (someone else made a changed that conflicts with yours, and if everyone else is checking in often, you're the one that has to deal with all the conflicts).  The more things you're working on at once, the more likely that one set of changes becomes dependant on another and you simply can't check your files in until all the changes you're working on are complete.  Work on one set of related changes at a time and check those changes in to avoid not merging your changes often.

Check-in often.
SCC provides developers the ability to keep a history of their changes.  But, this only works if you check your changes into the SCC system.  When you have something that compiles, check it in.  The more often you check changes into the SCC system the less likely you'll get into a situation where you have to deal with merge conflicts.  The more often you check changes into the SCC system the least complex the changes will be.  If the changes are not complex and you do run into a merge conflict, the less work will be involved in resolving the conflict.  Do your sanity (and the sanity of your team mates) a favour and check in often.  See next practice.


Avoid leaving changes overnight.
Check in your working changes before you leave for the day.  If it compiles and works (unit tests pass) there's likely no harm to checking in.  Leaving work for an extended period of time means it's that much harder to get back into that mindset; if you check in and describe the check in, you now have a history of the day's changes with an annotation making it easier to get back in that mindset.  But, since you've checked the files in, you may not need to get back into that mindset (if you didn't check in, you *must* get back in that mindset in order to check in).

Never destroy SCC content.
SCC offers the ability to get back to a project state at any time in the past.  If you destroy content from the system, this incapacitates this ability.  It goes against keeping any sort of history of a project to destroy content, so don't do it unless you intend never to make use of the history for that project (i.e. you're destroying and entire project and you never intend to work on it again or support it).

Don't Bypass Copy-modify-Merge
Eventually you'll be in a situation where you need to edit a file at the same time as another person.  In this case you'll need to merge your changes.  The copy-modify-merge model accepts this inevitable fact and makes merging a first-class citizen of your development process; not some nebulous process that occurs only occaisionally.  With a properly designed system the need to merge should be minimized.  I've seen teams instigate a policy that you must lock the file before you modify it.  I've also seen teams configure a SCC provider to automatically lock a file when changes are made to it.  This is the wrong thing to do on software development teams.  It leads to one of two things: 1) people just stop working when they can't lock the file they need to edit; or 2) they end up forcing copy-modify-merge that isn't supported by the tools they're using, which often leads to human errors and errors in merging.

I hope to continue this series as time goes on, if you have suggested topics, please comment.  I expect to keep pretty generic; but could get SCC-system-specific, if there's interest.

kick it on DotNetKicks.com

A Upcoming Pandemic of Domain Anaemia

There's a well-known anti-pattern called the anaemic domain model[1][2].  This anti-pattern basically says domain entities, chronically, have little or no behaviour (remember, object-oriented design is about attributes and behaviour).

It should be obvious that a domain model that isn't truly object oriented is a domain model with a problem.  But, let's look at other reasons why the Anaemic Domain Model is an anti-pattern.  Your Domain is the nexus, the essence, of your system.

An anaemic domain model is basically a reporting system.  Each "Entity" becomes, essentially, a query.  This is fine, reporting systems are necessary and prevalent.  But, to shoe-horn a domain model on top of this leads away from good reporting patterns that could add value and increases complexity, needlessly.  The designers spend most of their time trying to force entities on the system, without recognizing the basic reporting nature of the system.  This usually leads to "reports" that have to pull in multiple domain "entities" to generate the report--rehydringing data into an entity (usually through some sort of ORM) with no value added.  i.e. an ORM that will manage the child-parent relationship (and either pre-load or lazy-load aggregates) doesn't provide much value here.

The worst case scenario with an anaemic domain model is that there really is behaviour there; but it's not handled in the domain entities; it's handled in a different layer.  This is a problem because this circumvents the whole point of a domain model and layering. 

One indication of anaemia is that most of the domain classes  simply contain attributes.  Anyone familiar with patterns should recognize this as a Data Transfer Object, not a Domain Entity.  There's nothing wrong with DTOs, they're very important in almost all systems with any sort of complexity; but they're not Domain Entities.  Let's be truthful, there are systems with little or no behaviour in the domain; and that's not a bad thing.  Systems like this likely don't need a Domain Model and may not need techniques like Domain Driven Design.  The quicker people recognize that, the quicker they can be using a more appropriate architecture and design.  In some extreme cases the anaemic-domain-entity-DTOs service other DTOs

Now, where am I going with this?  Well, there's been a series of guidance out of Microsoft Patterns and Practice about some application "patterns".

First, let me describe what a pattern is.  A pattern is a way of "documenting a solution to a design problem" [3].  First, for it to be a pattern, it needs to detail the problem and it's context, then provide a solution.  The latest "patterns" from P&P do not detail the problem or a context.  They're simply architectural descriptions.

Now the association between the Anaemic Domain Model and the latest P&P guidance.  In 3 of the 5 recently publish "patterns" the following is detail is included: "A Domain Entity pattern is used to define business entities that contain data only."  This is the very definition of an Anaemic Domain Model.  Plus, in the RIA pattern the following, contradictory, detail is included: "Domain entities are responsible for implementing business rules.  Entities from the domain model represent business objects that contain data and implement behavior [sic]. In other words, the business objects are responsible for implementing business operations and interacting with other business objects."

This is disconcerting because historically sample code and guidance from Microsoft is simply reused without thought.  This leads to poorly designed and architected applications, and the .NET community as a whole is seen as one that produces poor-quality code and design.  Without context about the problems these patterns try to solve, they will be misused—likely forced upon contexts and situations where they don’t fit, simply because “they’re from Microsoft”.

[1] MF Bliki- AnemicDomainModel

[2] Anemic Domain Model - Wikipedia, the free encyclopedia

[3] Design pattern (computer science) - Wikipedia, the free encyclopedia

Digg ThisDotNetKick This

It’s More Than Syntax

Writing good software is not just about adhering to a programming language's syntax.  No programming language syntax enforces good design nor does it enforce good programming in all circumstances.

I've seen many systems that compiled perfectly fine; but they weren't good systems.  Some exhibited reliability problems.  Some exhibited maintainability problems.  Some exhibited performance issues.  Some exhibited resistance to change.  All eventually failed at some point; either the system could not change at the required pace, or could never attain an acceptable reliability, etc.

What was wrong with these systems?  The programmers didn't look beyond the syntax of the language.  They didn't accept that programming was about correctly constructing software, not simply writing syntactically correct code.  In almost all cases, the projects didn't have design experience to guide the programming.  The lack of leadership meant that other factors like time-to-market completely dominated the quality of code written.

Now, I'm not saying that big-design-up-front makes for better software.  Big-design-up-front may help with some of the problems of these systems; but it doesn't help with others and it introduces more problems.

Any good software system needs a certain amount of design, up front--you need to know what you're going to be working on both from a requirements point of view and an architectural point of view.  The lowest common denominator is generally some architectural vision based upon established wisdom.  With some systems, this doesn't even need to be complex.  Just enough to guide everything the programmers do.

With any system, its goal is to fulfill the requirements of the stakeholders.  Some requirements (often many) are known at the onset of the project; but some are elicited throughout the evolution of the system.  I say system instead of project because a successful system generally consists of more than one project.  A project could be as granular as a particular iteration, or may be as wide as a project release.  In either case a system changes over time for as long as the system is in use.  To ignore that is to doom the system to failure.  Ignoring the fact that the system must change over the life of the system usually results in things like "requirements sign-off", lack of iterations, big-design-up-front, etc.

In any case, gauging the correctness of a system based on errors/warnings from the compiler is a mistake.  The architecture of the system must utilize established patterns for it to be maintainable and for it to be able to evolve over time.  The development of the system must employ unit testing to ensure the correctness of the system in light of its evolution.  The system must be monitored over its evolution to ensure it's following the architectural design.  If it's not following the architectural design, find out why; and re-evaluate the architecture if need be.

In short, good programmers know much more than simply the syntax of the language they're using.

 

Digg ThisDotNetKick This

House of Cards Design Anti-pattern

I've had this anti-pattern in my head for years.  It's an observance of some projects and methodologies that I've witnessed over the years.  I believe it's a form of Voodoo Programming, Programming by coincidence, and is often a side effect of Cargo Cult Programming.

Anti-Pattern Name
House of Cards Anti-pattern

Problem
A problem occurs when software is written that works in a specific observed scenario but no one knows why it works in that scenario.  Observation of "working" is taken as enough evidence of completeness.  It is very often not enough to observe something working in one scenario for the software to be considered "correct".

This is often a result of continual hacks in sole response to correcting bugs without consequence to design or maintainability.  Repeated hacks (cards) are are placed on top of other hacks until something has the appearance of "working" then all development on it stops and no one wants to go near the code again for fear of breaking it.

At the very least, House of Cards design is fragile, hard to maintain, un-agile.  Worst case it's is of low quality and prone to error and data lose.

This is a general sign of cowboy coding.  I means there is no acceptable methodology, and no real management.  There's little development direction, and likely no development leadership (at least none with any meaningful experience).  Features are generally driven solely by an external source that communicates directly with developers.

Symptoms

When reviewing code or questioned about code, developers respond with comments like "don't touch it, it works", or "we don't want to change it because it works".  There's a reluctance to change the code because no one really knows why it works.  The code stagnates, new features are slow to be implemented, and there's a general un-assuredness about the code.

The code is generally procedural, although following object-oriented syntax.

Refactored Solution

Establish experienced development leadership.  Establish a development methodology that separates the stakeholders from the developers.

Invoke Agile methodologies to manage the requirements of the project and begin Agile redesign of the code employing unit testing, refactoring, patterns, etc.  Aggressively refactor the code adding unit tests to test for specific problems as they arise, until the code is robust and reliable.  Mandate adherence to SOLID principles: classes adhere to Single Responsibility Principle, Open-Closed Principles, Liskov Substitution Principle, Interface Segregation Principle, and uses the Dependency Inversion Principle

Digg ThisDotNetKick This

Unable To Step Into .NET Source

I began getting a problem a while ago that I was unable to step into the .NET source in Visual Studio 2008.  It happened suddenly, and I noticed it shortly after installing SP1.  Given my observation it appears to be due to upgrading the SP1; but I couldn’t find anyone else not having the same problem.  I had another computer where it worked, so I basically put it aside.

Today I had a chance to have a closer look.  I had configured 2008 (RTM, not SP1) to get the .NET source based on Shawn Burke’s blog and had not encountered any problems.  Once I upgraded to SP1 and checked “enabled .Net source stepping”, I all I ever got when trying to step through source is a dialog asking me for the location of the CS file.

What I had configured was to place the debug symbols into a folder in the Visual Studio 2008 user directory (c:\Documents and Settings\PRitchie\My Documents\Visual Studio 2008\Symbols, for example).

Despite creating a new subdirectory for SP1, I still could not step through the source.

It wasn’t until I moved the directory down the hierarchy that I finally got some joy.  I first tried it on the root and it worked fine.  I then tried it as a sub directory within my documents and it worked fine.  I imagine that the path was longer that 260 and rather than present the user with an error with that detail it assumed it couldn’t find the file it was looking for and asked the user for the location of it.  But, I’m guessing.

Hope this helps someone else.

DotNetKicks Image

Pass-through Constructors

Pass-through constructors is a term I use to describe parameterized constructors that have none of their own logic and simply pass parameters to the base class.  For example:

    public class BaseClass

    {

        private String text;

        public BaseClass(String text)

        {

            this.text = text;

        }

    }

 

    public class DerivedClass : BaseClass

    {

        public DerivedClass(String text)

            : base(text)

        {

        }

    }

DotNetKicks Image

Pontificating Virtual Parameterized Constructors in C#

Tom Hollander recently posted about a change he required to the Enterprise Library for date/time validation.  He had to create a new class (rather than modify the Enterprise Library) that derived from another, defective class.  One of his complaints was that in order to effectively implement the base class he had to also write matching constructors that simply called the base class.  His suggestion was effectively to add the concept of virtual parameterized constructors to C#.  I detail “parameterized constructors” because C# already effectively has virtual default constructors.  In the following example the base constructor (Form()) is automatically called by the derivative:

    public class MyForm : Form

    {

        public MyForm()

        {

        }

    }

Virtual parameterized constructors are not new, and from a mere language standpoint this seems reasonable.  Pragmatically though, I believe, this is another story.  It seems logical to be able to simply inherit the parameterized constructors of the base class; but, there are so many times that this isn't the case or some generally accepted principles that would be contravened by a language addition like this.

Let's first look at the open/closed principle (OCP).  The OCP suggests classes should be open for extension but closed for modification.  Robert Martin suggests [1] properly designed class hierarchies that obey OCP implement an abstraction; i.e. derive from an abstract class or implement an interface.  For example:

public interface IShape

{

    void Draw(Graphics graphics);

}

 

public class Rectangle : IShape

{

    //...

    public void Draw(Graphics graphics)

    {

        ///...

    }

}

 

Second, let's look at the "prefer composition over inheritance" principle.  The effect of a language change like this on a design that prefers composition should be fairly obvious.  Here's an example of this principle:

public interface IPolygon {

    void Draw(Graphics graphics);

}

public sealed class Polygon {

    private readonly Point[] points;

    public Polygon(Point[] points) {

        this.points = points;

    }

    public void Draw(Graphics graphics) {

        for(int i = 1; i < points.Length; i++) {

            graphics.DrawLine(Pens.Black, points[i-1], points);

        }

    }

}

 

public class Rectangle : IPolygon {

    private readonly Polygon polygon;

    public Rectangle(Point location, Size size) {

        Point[] points = new Point[5];

        points[4] = points[0] = location;

        points[1] = new Point(location.X + size.Width, location.Y);

        points[2] = new Point(location.X + size.Width, location.Y + size.Height);

        points[3] = new Point(location.X, location.Y + size.Height);

        polygon = new Polygon(points);

    }

    public void Draw(Graphics graphics) {

        polygon.Draw(graphics);

    }

}

 

Obviously there is no way to use virtual parameterized constructors here.

Clearly, designs that take into account OCP and prefer-composition-over-inheritance would not benefit from a "virtual parameterized constructor" language addition.

Finally, let's look at why a class might have many constructors causing such friction for derivatives.  There's many reasons why a class might have many constructors.  I believe all are indications of a poorly designed class.  My first thought would be that many constructors is a result of a large class and that the large-class-code-smell should be an indication for redesign.  A large class could be in an indication of a motherclass; but in either case this is likely a single responsibility principle (SRP) violation and the class is doing much more than it should and be redesigned.  If the class isn't large but has many constructors, this was likely done not in response to how the class should/would be used but to cover every possible way of constructing the type.  This would then be a YAGNI violation and the number of constructors should simply be pared down.

But, what about when you have to deal with poorly design hierarchies and don't have the ability to modify them?  A valid point; but, simply for the lack of friction of writing pass-through constructors I don't think adding to the language to support poorly designed classes is a good for the language or its developers.

While an addition like virtual parameterized constructors seems benign, its limited actual usefulness makes the effort not worth the reward.  Plus, it introduces greater abilities to create poorly designed types.

[1] http://www.objectmentor.com/resources/articles/ocp.pdf

DotNetKicks Image
More Posts Next page »