Good Old OOA, OOD, OOP Techniques are Economically Sound

I was recently asked a general question on OO (object orientation). The question was: "I have a class with some members that I don't need in a particular child class. How do I hide the unneeded features?"

There are a couple of answers, which I will cover in this article. Answers that are about good old straight forward OO techniques!

I want to take a minute to encourage everyone about back to basics concepts. One casualty of the current bad economy seems to be sound development practices. You will hear a lot about Web programming, cloud computing, tools and components, but it seems there is little talk about good old object oriented (OO) anything. Modeling, design, UML, patterns, and refactorings are as relevant and useful as ever—actually more so. I wonder whether the layoffs and economic uncertainty hasn't created a kind of "just get the job done" atmosphere where first principles are discarded. I encourage you not to let this happen where you work. Languages come and go, some sticking longer than others. Technical challenges are zooming into the stratosphere of complexity, but clouds and immagical-imaginary, magical-tools won't solve all the problems without thinking being done by human beings. The best part of all of this is that reading, learning, thinking, and honing your technical skills as one of the best economical bangs for your buck available.

Stepping down from soap box, let's get started.

Defining the Problem Space

The problem as defined by my questioner is basically how are members of classes hidden in child classes if they are not needed? You have a potpourri of possibilities:

  • Without sounding too flippant, one answer is who cares? If you don't need it don't use it. There is an infinite amount of space in the digital world. (It's like the old joke: "how much does a gigabyte weigh?"
  • If you didn't like the first option you'll hate this one even more: OO is hard to produce; the members are probably in the wrong class. (I am not kidding here people these are valid answers)
  • You can always add a new member with the same signature in the child class and pretty effectively quash that nasty dead weight (see Listing 1). Hiding members is a bit ugly and polymorphism, reflection, and the DirectCast will actually break this approach
  • Or a pretty good answer is to use a faC'ade class. A faC'ade is a class that selectively exposes the elements of another class or classes. (The rest of this article focuses on our friend the FaC'ade pattern.)

Listing 1: Hide an existing member in a parent class by stomping on the signature you'd like to block.

Module Module1

    Sub Main()

      Dim o As HideMyMethod = New IWillHideYou()
      Dim p As IWillHideYou = New IWillHideYou()
      o.HideMe()
      p.HideMe()

      ' Calls shadowing member in HideMyMethod.HideMe called
      DirectCast(p, HideMyMethod).HideMe()

      Console.ReadLine()

    End Sub

End Module

Public Class HideMyMethod
  Public Sub HideMe()
    Console.WriteLine("HideMyMethod.HideMe Called")
  End Sub
End Class

Public Class IWillHideYou
  Inherits HideMyMethod

  Public Sub HideMe()
    Console.WriteLine("IWillHideYou.HideMe Called")
  End Sub
End Class

In Listing 1 o actually calls the base class method—HideMyMethod.HideMe—even though the instance of o is IWillHideYou. The instance p actually calls the child class method, and even though p should call IWillHideYou.HideMe because of the DirectCast HideMyMethod.HideMe is called. And, of course, with reflection the class consumer could circumvent the shadowing of HideMe done by IWillHideYou. (Note: using the same signature in a child class is called shadowing in VB and the Shadows modifier—as in, Public Shadows Sub HideMe()—will eliminate the warning caused by implicit shadowing.

Using the FaC'ade Pattern to Hide Deadweight or Reduce Complexity

Over time classes can end up with too many members to make them easy to use. The general rule of thumb is that a class should have about a half dozen public members and be responsible for one basic kind of solution. What happens in reality is that junk is added to classes over time and eventually those classes become hard to own and hard to use. The next thing that happens is that someone wants to re-write everything. Aside from the fact that one should generally not re-write everything, rather one should refactor things, re-writing is risky business.

Caveat: Bad OO can become cumbersome to consume even if you produced it (some time ago).

When code is re-written the likeliest thing to happen is that code that works will be broken. The result is one goes from code that is hard to use and own to code that is just broken. At least with Refactoring code is changed in carefully prescribed ways without changing its observable testable behavior. One such Refactoring is to introduce a faC'ade.

By using a faC'ade you can hide complexity behind the faC'ade making the existing stuff easier to consume while hiding all of the murky complexity. Interestingly enough a faC'ade works with our problem, which is, hiding stuff you don't want to see or use. In Listing 2 another method is added to HideMyMethod. This time a faC'ade is created to expose only the method—the new one—desired.

Listing 2: The faC'ade pattern let's you simplify interfaces by concealing unneeded members.

Module Module1

    Sub Main()
      Dim obj As HideMyMethodFacade = New HideMyMethodFacade()
      obj.DontHideMe()
      Console.ReadLine()

    End Sub

End Module

Public Class HideMyMethod
  Public Sub HideMe()
    Console.WriteLine("HideMyMethod.HideMe Called")
  End Sub

  Public Sub DontHideMe()
    Console.WriteLine("I am available")
  End Sub
End Class


Public Class HideMyMethodFacade
  Private obj As HideMyMethod = New HideMyMethod

  Public Sub DontHideMe()
    obj.DontHideMe()
  End Sub
End Class

In Listing 2 HideMyMethod is easier to use because the unneeded methods are hidden behind the HideMyMethodFacade class. The consumer doesn't even have to know HideMyMethod.HideMe exists. By the way WCF services are an implementation of the FaC'ade pattern.

For more on OO design check out my book UML DeMystified from Osborne-McGraw-Hill, check out http://www.dofactory.com, or my blog at http://community.devexpress.com/bloks/paulk.

Summary

It is possible to change the exposed public members of a class without breaking the class by using the FaC'ade pattern, which is actually a design pattern and a refactoring. Keep in mind that economic paranoia is no excuse for taking shortcuts or throwing good techniques out the window even though your pointy-headed manager might think so. (I know you aren't taking shortcuts, but someone in the cubicle next to you might be. Tell him or her to quit it.)

I get my ideas for columns from problems I experience or from readers. (I don't generally mention the inspirer unless they provide a good solution.)



Comments

  • Doesn't C++ directly allow this!!!

    Posted by Alok Govil on 04/04/2009 01:34pm

    >> "I have a class with some members that I don't need in a particular child class. How do I hide the unneeded features?"
    
    C++ allows:
    
    class D: public Class B // Most common
    class D: protected Class B
    class D: private Class B
    
    The last two can hide private and protected members of B from D.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

  • As a development and deployment platform, RHEL offers an efficient, scalable, and robust operating environment with certified security and flexible deployment options in physical and virtualized environments. To assess and quantify the business benefits of RHEL, IDC recently conducted in-depth interviews with IT staff members of 21 companies using RHEL servers. The organizations represent a broad range of industries and have an average of 22,700 employees. RHEL servers accounted for 23% of the servers …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds