May 2008 - Posts

Spaces or Tabs?

In this day and age it seems silly to get into a discussion about whether your companies coding guidelines should have a section mandating either spaces or tabs for indents.  Tabs are clearly more flexible, but I really don't think it matters at all; people can easily read code that contains spaces or tabs.

But, Microsoft has departed from what seems to be the rest of the world and is mandating spaces in their new Microsoft Source Analysis Tool for C#.

Word is that an update will not only mandate spaces but mandate 4 for indents.

Again, I don't think it's much of an issue; except Microsoft Source Analysis Tool for C# doesn't offer a rule to mandate tabs over spaces.  They're not providing a tool for organizations to use to enforce local coding guidines, but providing a tool to mandate Microsoft's coding guidelines.

The tool can be downloaded here and a discussion on tabs can be found here.

kick it on DotNetKicks.com

Resharper 4.0 EAP Settings and Installing Latest Build

The 4.0 EAP tends to do a full uninstall before installing (it's pre-beta, pre-alpha even; so it's no wonder).

This tends to blow away your settings changes.  If that's a pain point for you, the settings are stored in "%userprofile%\application data\jetbrains\resharper\v4.0\vs9.0".  There are a couple of xml files in there that store your settings.  Before you upgrade to the latest build, just copy those to another directory.

 It's very likely that the format of these files has changed since the last build so copying the backups over the new version could possibly make Resharper to blow-up.  So, use with caution.

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

DevTeach Toronto 2008

Well, DevTeach Toronto 2008 is just wrapping up.  It was a fantastic conference, many world-class developers, world-class presenters, and world-class topic.  Congrats to all.  It was well organized that the tracks that I took part in were well designed.

What's special about conferences like this is the ability to interact with peers and leaders from across our industry, something you can't get any other way.  If you went to the conference and didn't talk to anyone, you really missed out.

The next is DevTeach Montreal in December.  I highly recommend it.

en POCO

First of all, let me describe what a POCO is.

"POCO" is a Plain-Old-CLR-Object.  This means that it does nothing more than be that encapsulated type implemented by that class.  It has SRP and has no other responsibility than that responsibility for which is abstracts.  It has no coupling to other assemblies that are outside of it's responsibility, and ignorant of anything else.  POCO is the .NET side of POJO (Plain-Old-Java-Objects) on the Java side.  POJO was a response to the huge problems that occurred years ago with certain persistence frameworks and a requirement for those classes to know about their own persistence.  POCO is really about Persistence Ignorance (PI); but the practice of SRP and SoC, when followed, result in POCO.

My next statement might see obvious to some; but it's kinda the reason for my post: any class that requires dependencies outside its responsibility to be pulled in isn't a POCO, by definition.  And this includes attributes.

Enter iPOCO. 

So, we've got a term that derives from a Java term (POJO) to specially mean a class that is decoupled from any trappings that aren't part of its behaviour, is completely abstracted and encapsulated.

Prepend an i to the term and you get iPOCO, a term that Microsoft is using as a buzzword for the ability of objects that are used with the Entity Framework (EF) to become presistable with that framework.  A object that is persistable with EF must implement 3 interfaces: IEntityWithChangeTracker, IEntityWithKey, IEntityWithRelationships.  iPOCO is a way to get those interfaces on your class without you having to manually add and implement them, simply by adding an attribute. (it performs some "magic" at build time--and as far as I can tell, is done post compile).

iPOCO is neither more nor less POCO, this is not POCO, it's the opposite of POCO.  Your type is not plain, it's decorated with an attribute.  That object is now coupled to that attribute and all that it brings with it.

That's why POJO/POCO were given a name, to make the practice explicit.  We're writing object-oriented software, it needs to use the basic features of OO: abstraction and encapsulation.

iPOCO == !POCO, If anything it's Persistence Ignorance Ignorance.

 

Posted by PeterRitchie | with no comments
Filed under:

DevTeach 2008

Well, I'm off to DevTeach Toronto 2008.  Track me down and say hi if you're going...

Posted by PeterRitchie | with no comments
Filed under:

RFC: Conditionals on false

Just a small request for comments.  Oren prefers

    if (GetTrueOrFalse() == false)

...instead of

    if (!GetTrueOrFalse())

Coming from 18+ years of C/C++ based language programming, I find either equally readable; but, I'm not always the one reading my code.

What are you thoughts?  Do you prefer the negation operator (!) or explicitly comparing with the false keyword?

Posted by PeterRitchie | 11 comment(s)
Filed under: ,

Fundamentals of OOD, Part 2 - Encapsulation Scope

Let's look at the ubiquitous Person concept.  It might seem logical that an application that deals with people should have a Person interface for classes to implement.  For example:

public interface IPerson
{
                String GivenName { get; set; }
                String SurName { get; set; }
                IAddress Address { get; set; }
}

At first glance this seems fine.  The IPerson interface defines attributes that the application uses with most scenarios dealing with types of IPerson, it's "well encapsulated".  But, the person concept is much more broad than what IPerson is modeling.  IPerson hasn't fully encapsulated the person concept.  A person could have parents, age, weight, height, etc.  The application doesn't need this information so it's narrowed the concept of person to fit its needs. This is an incomplete abstraction.  The type that the application needs (that is currently IPerson) should be fully abstract.  Based on the IPerson interface, a better abstraction would be ILocatableIndividual.

Let's look at the opposite of not fully encapsulating a concept. 

Let's look at another common concept, the Invoice:

public class Invoice
{
                Customer BillToCustomer { get;set; }
                Customer ShipToCustomer { get;set; }
                Datetime InvoiceDate;
                ICollection<InvoiceItem> InvoiceItems { get; }
                Single ShippingAndHandlingPrice { get; set; }
                Single CalculateSubTotal();
                Single CalculateTotal();
                Single CalculateGrandTotal();
                PurchaseOrder PurchaseOrder { get; set; }
                void Print();
}

Again, seems like a reasonable encapsulation; but it has an issue. 

There's a fundamental principle of OOD called the Single Responsibility Principle.  Robert Martin interprets the principle as "there should never be more than one reason for a class to change.".  A class should model a single abstraction.  For that abstraction to remain abstract the modeled class should have a single responsibility.  In the case of Invoice, the invoice concept should only model behaviours and attributes of an invoice.  An invoice does not print, something or someone else prints it.  With the above Invoice definition should printing need to change Invoice must also change, event though what the invoice *is* doesn't change.  Invoice is now coupled to how printing occurs.  In Martin's terms, Invoice now has two reasons for it to change: when invoice attributes change, and when how printing occurs changes. 

The Invoice class should be refactored by moving the Print method to another class.  Likely this would involve MVC, or MVP where a view would be responsible for the "printed view" and a controller or presenter would be responsible for communicating with the model (Invoice).

 

kick it on DotNetKicks.com

Fundamentals of Object-Oriented Design (OOD) Part 1

With increased usage of patterns and situationally specific strategies, people sometimes lose sight of the concepts and principles behind these patterns and strategies and fail to follow them when they're not using patterns or strategies.  I feel it's good to periodically review the fundamental concepts and first principles.

Object Oriented Design (OOD) attempts to help with the complexity of designing, writing, and maintaining software.  It attempts to allow building of software by modeling real-world objects.  As with any tool, it can be used improperly, but OOD attempts to facilitate simplicity, robustness, flexibility, etc..  OOD has many fundamental concepts.  Some of these concepts include modularity, encapsulation, and abstraction.  OOD deals with modeling behaviour and attributes of real-world objects.

Modularity is a technique of composing software from separate parts.  At the lowest level of an Object-Oriented Programming Language (OOPL), this is the definition of a type (a class or a struct in C#/C++).  Depending on the platform there may be various other levels of modularity.  In C#, for example, modularity can occur at other levels like module (source file), namespace, netmodule, assembly, etc.  Modularity is a form of encapsulation.

Encapsulation is a technique of hiding implementation details, grouping them together.  In OOPL, the lowest level of encapsulation is the type level (again, class/struct in C#/C++).  Implementation details (data) is separated from behaviour of a type.  In some OOPLs both behaviour and attributes (properties, for example in C#) are separated from behaviour.  This allows clients to decouple or to be not dependant on those implementation details. Encapsulation is a form of abstraction.

The ability to encapsulate related behaviour, attributes, and implementation allows programmers to utilize abstraction.  Abstraction facilitates separation.  OOPLs allows programmers to keep concepts separate by abstracting them from one another.  Keeping abstract concepts separate allows these concepts to evolve and be used independently.  Properly designed types allow abstraction; a File class can abstract the file system away from a particular file, for example.  The file system is part-and-parcel when dealing with files; but while dealing with a File object, it is abstracted away.

Good OOD has as little dependencies between parts as possible.  This is called lack of coupling.  One part that uses another part means the part depends on that other part.  Changes to the second affect the first.  Good OOD also has parts that contain related behaviour and attributes.  This is called cohesion.  If all the behaviour and attributes are generally used together in each scenario, the part has high cohesion.  If only some behaviour or attributes are used in each scenario, the part has low cohesion and likely should be split up.  Some people only view cohesion and coupling at the class level, I've purposely said "part" because I believe these concepts need to live throughout the modeled system, from class-level details, to modules, to namespace, to assemblies, to layers, to components, to systems, etc.

I will continue this series with the fundamental OOD principles that all good patterns should enforce.

kick it on DotNetKicks.com