JAL Computing

C++COMProgramming .NET Mac Palm CPP/CLI Hobbies

 

Home
Up

Chapter 23 "Backward Compatibility"

In this brief chapter, we examine the problem of backward compatibility. If we add a new "fill" feature to the DrawableShape class, it is desirable that this new feature does not break the existing Draw application. One way to solve this problem is to rely on our decision to program to the IDrawableShape interface and the ability of the DrawYourself method to encapsulate or hide the actual implementation of the drawing behavior. In this chapter we create a new interface IFillable, implement the new FillColor property in the Triangle class and add the new fill behavior to the Triangle DrawYourself method. Although the existing Draw application cannot set or get the new FillColor property, the new fill behavior is displayed by the Triangle at runtime. By programming to the abstraction IDrawableShape and the DrawYourself method, there is no need to recompile the Draw application.

The IFillable Interface

First we define a new library project JALInterface1 and a new interface IFillable that simply provides for a new property of type Color called FillColor. This is not a very realistic interface. A sophisticated interface might include properties such as IsFilled, FillBrush, IsTransparent etc.

using System;
using System.Drawing;
namespace
JALInterface1
{
    public interface IFillable
    {
        Color FillColor
        {

            set
;
            get
;
        }
    }
}

This project is compiled in release mode.

Update the DrawablePlugIns Project

We can now update the DrawablePlugIns project to implement the IFillable interface. We add a reference to the JALInterface1.dll to the project. We then use the FillColor property to color in the Triangle on DrawYourself(). Here is the modified DrawablePlugIns project:

using JALInterfaces; 
// project references JALInterfaces.dll
// Create a new concrete class Triangle to be loaded dynamically
[Serializable]
public
class Triangle : AbstractDrawableShape, JALInterface1.IFillable
{
    private System.Drawing.Color fillColor= Color.White;
    public System.Drawing.Color FillColor
    {
        get{return fillColor;}
        set{fillColor= value;}
    }

    public override void DrawYourself(Graphics g)
    {
        Pen p=
new Pen(Color,BrushWidth);
        Point point1=
new Point(Position.X+Size/2,Position.Y);
        Point point2=
new Point(Position.X,Position.Y+Size);
        Point point3=
new Point(Position.X+Size,Position.Y+Size);
        Point[] points= {point1,point2,point3};
        g.DrawPolygon(p,points);
        Brush b=
new SolidBrush(fillColor);
        g.FillPolygon(b,points);

    }
}

Again, the project is compiled in release mode. We then drag both the DrawablePlugIns.dll and JALInterface1.dll to the TestDrawFactory "plugins" folder.

The New Fill

That's it! There is no need to modify the TestDrawFactory project or exe. Although the Triangle class and version has changed, the Triangle class still implements the same IDrawableShape contract. We are still able to dynamically load the new Triangle class as an IDrawableShape type.

// only load into type based factory
// if type implements IDrawableShape
if (typeofnull)
                && ((t.Attributes & TypeAttributes.Serializable) != 0))
{
    typeFactory.Add(t);
}

When the new Triangle class is loaded at runtime, the new behavior is implemented through encapsulation.

Cool!

Note: You should be able to demonstrate the same behavior using a class hierarchy. If you extend the class hierarchy, you should still be able to access the public methods and fields of the base class without recompiling the client application.

 
Send mail to [email protected] with questions or comments about this web site. Copyright © 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 © 
Last modified: 08/04/09
Hosted by www.Geocities.ws

1