Re: constructors/static methods and inheritance query

From: Baavgai (brettmc_at_gmail.com)
Date: 09/13/04


Date: 12 Sep 2004 19:27:34 -0700

Ok, here's a quick example. Consider two simple interfaces.

public interface IBaseLine { int X1 { get; } int X2 { get; } int Y1 {
get; } int Y2 { get; } }
public interface ILine : IBaseLine { double GetDistance(); }

Here's the static initalizer version.

public class BaseLine : IBaseLine {
private int x1, y1, x2, y2;
public BaseLine(int x1, int y1, int x2, int y2) {
this.x1=x1; this.x2=x2; this.y1=y1; this.y2=y2;
}
public static BaseLine Initialize(int x1, int y1, int x2, int y2)
{
return new BaseLine(x1, y1, x2, y2);
}
public static BaseLine Initialize(string x1, string y1, string
x2, string y2) {
return new BaseLine(
Convert.ToInt32(x1), Convert.ToInt32(y1),
Convert.ToInt32(x2), Convert.ToInt32(y2)
);
}

public static BaseLine Initialize(string point1, string point2) {
string[]
aPoint1=System.Text.RegularExpressions.Regex.Split(point1,
@"(.+),(.+)");
string[]
aPoint2=System.Text.RegularExpressions.Regex.Split(point2,
@"(.+),(.+)");
return Initialize(aPoint1[1], aPoint1[2], aPoint2[1],
aPoint2[2]);
}

public int X1 { get { return this.x1; } }
public int X2 { get { return this.x2; } }
public int Y1 { get { return this.y1; } }
public int Y2 { get { return this.y2; } }
}

Here's the constructor version.

public class BaseLine : IBaseLine {
protected int x1, y1, x2, y2;

public BaseLine(int x1, int y1, int x2, int y2) {
Initialize(x1, y1, x2, y2);
}

public BaseLine(string x1, string y1, string x2, string y2) {
Initialize(x1, y1, x2, y2);
}

public BaseLine(string point1, string point2) {
Initialize(point1, point2);
}

private void Initialize(int x1, int y1, int x2, int y2) {
this.x1=x1; this.x2=x2; this.y1=y1; this.y2=y2;
}

private void Initialize(string x1, string y1, string x2, string
y2) {
Initialize(
Convert.ToInt32(x1), Convert.ToInt32(y1),
Convert.ToInt32(x2), Convert.ToInt32(y2)
);
}

private void Initialize(string point1, string point2) {
string[]
aPoint1=System.Text.RegularExpressions.Regex.Split(point1,
@"(.+),(.+)");
string[]
aPoint2=System.Text.RegularExpressions.Regex.Split(point2,
@"(.+),(.+)");
Initialize(aPoint1[1], aPoint1[2], aPoint2[1], aPoint2[2]);
}

public int X1 { get { return this.x1; } }
public int X2 { get { return this.x2; } }
public int Y1 { get { return this.y1; } }
public int Y2 { get { return this.y2; } }

}

It looks pretty much the same and has been changed minimally, now for
Line.cs. The static style:

public class Line : ExampleConstructor.ILine {
private BaseLine bLine;

public Line(BaseLine bLine) {
this.bLine=bLine;
}

public static Line Initialize(int x1, int y1, int x2, int y2) {
return new Line(BaseLine.Initialize(x1, y1, x2, y2));
}

public static Line Initialize(string x1, string y1, string x2,
string y2) {
return new Line(BaseLine.Initialize(x1, y1, x2, y2));
}

public static Line Initialize(string point1, string point2) {
return new Line(BaseLine.Initialize(point1, point2));
}

public int X1 { get { return this.bLine.X1; } }
public int X2 { get { return this.bLine.X2; } }
public int Y1 { get { return this.bLine.Y1; } }
public int Y2 { get { return this.bLine.Y2; } }

public double GetDistance() {
return Math.Sqrt(Math.Pow(bLine.X2-bLine.X1, 2)
+Math.Pow(bLine.Y2-bLine.Y1, 2) );
}

Note that we have to do a lot of reimplementation here. Now, the
inherited version.

public class Line : BaseLine, ILine {
public Line(int x1, int y1, int x2, int y2) : base(x1, y1, x2,
y2) {}
public Line(string x1, string y1, string x2, string y2) :
base(x1, y1, x2, y2) {}
public Line(string point1, string point2) : base(point1, point2)
{ }

public double GetDistance() {
return Math.Sqrt( Math.Pow(x2-x1, 2)+Math.Pow(y2-y1, 2) );
}
}

Currently, the big difference here is that we don't have reimplement
all those public ints. Another bonus is that our constructors have
been simplified. Also, we don't have to really know about how our
parent does it's thing, only that we have to pass the data along.

I'm not sure if the example gives you ideas on how to streamline your
code. I can only tell you that I've worked on many large scale
projects where this kind of OOP approach has made life much simpler six
months later. I once challenged a comp sci professor on why my overuse
of globals was a problem. None of her examples really convinced me,
she finally just said, "trust me, from experience, it's bad." She was
right. Trust me, for OOP, strict is bad. ;)

For your code in particular, you might find some immediate benefit from
a Messenger type pattern. That is, rather than pass so many value
variations, roll parameters up into an object and pass that. For
example:

public class TreeConfig {
public string treeFileName=null;
public string blockFileName=null;
public System.IO.Stream treefile=null;
public System.IO.Stream blockfile=null;
public int keyLength;
public int cultureId;
public int nodesize;
public int buffersize;

public TreeConfig(System.IO.Stream treefile, System.IO.Stream
blockfile, int keyLength) {
this.treefile=treefile;
this.blockfile=blockfile;
Init(keyLength);
}

public TreeConfig(string treeFileName, string blockFileName, int
keyLength) {
this.treeFileName=treeFileName;
this.blockFileName=blockFileName;
this.treefile=new System.IO.FileStream(treeFileName,
System.IO.FileMode.CreateNew, System.IO.FileAccess.ReadWrite);
this.blockfile=new System.IO.FileStream(blockFileName,
System.IO.FileMode.CreateNew, System.IO.FileAccess.ReadWrite);
Init(keyLength);
}

protected virtual void Init(int keyLength) {
this.keyLength=keyLength;

this.cultureId=System.Globalization.CultureInfo.InvariantCulture.LCID;
this.nodesize=32;
this.buffersize=1024;
}
}

You can put all you custom constructors in a class like this and even
extend it for other objects. Like so:

public class TreeConfigX : TreeConfig {
public int prefixLength;
public TreeConfigX(string treefileName, string blockfileName, int
PrefixLength) : base(treefileName, blockfileName, PrefixLength) { }
protected override void Init(int keyLength) {
base.Init(keyLength);
prefixLength=keyLength;
}
}

Hope this gives you some ideas. Just using this messenger pattern
could probably simplify your code considerably.

Peace,
Brett

Aaron Watters wrote:
> Regarding my query visavis http://bplusdotnet.sourceforge.net/
>
> "Baavgai" <brettmc@gmail.com> wrote in message
news:<chuvjv$44k@odbk17.prod.google.com>...
> > I'm afraid that Nicholas is entirely correct.
> >
> > Static methods should be the exception, not the rule. I was
curious,
> > so I downloaded your project to see what was going on. You simply
> > don't need 90% of those static declarations.....
>
> I guess I'm being stupid. I don't see the benefit of getting rid of
> the static methods if I just make them into more constructors. Are
> you suggesting I could actually make the code simpler? If so I
> don't understand, please provide a small code sample.
>
> thanks, Aaron Watters
>
> ====
>
> I suggest a new strategy: Let the wookie win.



Relevant Pages

  • Re: Conditional Expression Testing for Nulls
    ... Classes that in turn have Students. ... public string Name ... public class Students: CollectionBase ... public int Add ...
    (microsoft.public.dotnet.languages.csharp)
  • Custom Object Structure
    ... get the Students and Student to nest properly...they actually nest under ... string firstName; ... public int GPA ... public class Students: CollectionBase ...
    (microsoft.public.dotnet.languages.csharp)
  • RE: How to I Start with C# Generics?
    ... > public Employee(int anId, string aName) ... > public int Id ... > public class GenericReferenceArrayListTest { ... > foreach (Employee e in employees) ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: How to build a Design Time PropertyGrid
    ... public class MyOBject ... public string Name ... public class MyObjectConverter:TypeConverter ... public int IndexOf(MyOBject value) ...
    (microsoft.public.dotnet.framework.windowsforms.designtime)
  • Re: XmlSerializer Collection with Collections
    ... > - a bunch of Option objects are contained within an OptionList ... > It is the extra level of object containment in the original version that ... >> public class TestSerializer ... >> public Question(string QuestionText, string Type, int Score, bool ...
    (microsoft.public.dotnet.xml)

Loading