Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Sunday, June 7, 2009

New designs, bad habits?

Here's a poser for the Object-Oriented development crowd.

OO tells us to encapsulate; to keep our object methods small (or, in the word of the jargon, atomic). Build objects that have simple methods, and that helps make the objects reusable. By the same token, objects also have state that is resposed in one or more member variables that may or may not be exposed by public properties. State, however, is tyically expensive, because persistence implies the memory and similar resources necessary to implement it.

Atomicity and state indirectly tend to work against each other. If my methods are too small, it necessarily suggests I'm going to push out elements to the class level. But if I push too much to the class level, I run the risk of creating classes that may need increasingly complex persistence mechanisms which, in turn, suggests a class that may be too broadly scoped. Yet if I decompose (or factor) an object too much, the fragmented design becomes a nightmare to maintain. It's not clearly a vicious circle, but it's a cautionary cliff to avoid.

Here's a shadowy example.

Suppose you have a class:

public class Something
{
    public void InterestingMethod1()
    {
    int ImportantVariable;
   ....do something interesting...
    }
}


And, without typing them here, suppose you have several similar methods in this class, each with a similar "ImportantVariable" declaration. Now, the casual observer would probably suggest that the repetition of that variable could indicate that it should be declared at the class level, as such:


public class Something
{
    int ImportantVariable;

    public void InterestingMethod1()
    {
    }
}


If, however, we start referencing "ImportantVariable" in our atomic methods, don't we reintroduce an old villain in our nice, object-oriented code? It seems to me that in a class of any appreciable size that does any appreciable work, factoring out common variables to the class level starts to look a lot like our old nemesis - global variables. We all know they're bad, don't we? That is, a substantive module wherein we declare a variable once, then it has scoping across all methods, allowing a single change to wreak all manner of unintended consequences. But isn't that precisely what member variables are allowing us to do in even moderately complex classes?

I won't pretend that I have the answer here, nor that this microexample is anything but a strawman example of the point. So I'll throw out the question- what is the "right" answer? When do our atomic methods have elements like local variables factored to the class scope, risking global behavior; when do our classes have members pushed down to methods for the sake of atomicity?

When, indeed? The floor is open for debate...

Friday, May 29, 2009

Hello...and an introductory musing

Greetings!!

Here begins a blog devoted to things computing and development oriented, ranging from the whimsical to the technical and everything in between. As topics evolve, feel free to contribute and comment for the benefit of everyone.

I've been a developer in the Windows environment for over 20 years, back in the halcyon days of Visual Basic, and later into the object-oriented world of Java, and more recently C# in ASP.NET. Most of my focus in recent years has been on database development in Microsoft SQL Server. I run a small Samba-based network at home, and have contributed to various technical publications over the years.

This brings us to today's inaugural post: a question of simplicity.

I'm a pretty simple person. I like plain mashed potatoes with a little butter and salt. I like hamburgers without a lot of gourmet trappings. And I prefer my programming code to be simple, too.

Having developed ASP.NET applications in C# for some time, it should come as no surprise to have encountered a situation with a site having multiple pages serving as content in conjunction with a master page. Each subsequent page gets a reference to a master page, and if programmatic access to elements of the master page is needed, you use the page's Master property to access them. Now, this works, and has obviously working for some time now, but it seems an unnecessarily complication.

The situation above, in my own head, screams as a matter of inheritance. In my ideal world, I would declare a base master page, a base content page, and derive all such pages in my projects:

// ideal ASP.NET subclass model
public class MyMasterPage: MasterPage
{
}

public class MyBaseContentPage: Page
{
}

public class AppContentPage: MyBaseContentPage
{
}

In this world, the source files for AppContentPage amount to a single ASPX file that includes the ASP:Content control markers for inclusion into the inherited master page, and the corresponding .cs code-behind file. That's it.

Now, you can "kinda" do this in ASP.NET today, but not quite. Note that these declarations omit the "partial" keyword - that's because they're hard classes. You can declare "hard" classes that reside in a web application folder called "App_Code", but as they're compiled to a separate assembly, they have no knowledge of master pages or other components. You can create page files with partial class declarations that inherit hard classes from App_Code, but you don't inherit the ASPX file that goes with it.

The inheritance model I dream of here eliminates the need for the "Master" keyword to access elements of the inherited master page, which I've always thought of as a bit of an ugly hack. For the notion of "installable" master pages, the inheritance notion also suggests that master page developers could be led more naturally to the implementation of standard interfaces to bridge the gap between the presentation and the content, not to mention the use of events to decouple the master page from its consumer. That "Master" keyword leads to ungainly and knarled code that, further, tends to gloss over design partitioning issues that, in turn, slow productivity.

As I noted, I understand you can "kinda" do the things I've discussed in ASP.NET, but not in a way (so far as I know) that truly embraces the notion of object-based inheritance.

Am I wrong? Have I missed some huge boat here?

Let me know.