views:

152

answers:

3

Hi,

I have 6 classes, which are all document types. All the document types have the same 8 fields. There is one class which consists of only these 8 fields. The rest of the classes have more fields. Some of these classes have the same fields (beside the 8 fields).

Example:

class Document: fields 1 to 8

class Form: fields 1 to 8 and field 9 and 10

class WorkInstruction: fields 1 to 8 and field 9 and 10

class Procedure: fields 1 to 10 and field 11

Hopefully this will make clear my point.

My question is, what is the best way to implement this? Should i make one or more interfaces, or should i use abstract classes?

Thnx

+2  A: 

Either make Document the base type of Form etc, or make a form have the extra fields and a reference to a separate Document (i.e. use composition instead of inheritance). In this case it sounds like inheritance would quite possibly be the best option, but it really depends on what you want to do with it. Do you have code which is meant to work on any document, including Form, WorkInstruction etc?

EDIT: For example, suppose you have a user interface control which can show the common parts of any document - i.e. the common 8 fields. That would take an instance of Document. You may want to be able to pass a Form or WorkInstruction to it directly - in which case it's best to derive from Document. Alternatively, when rendering a Form or WorkInstruction, you could create an instance of the control passing in the document part separately. i.e. it's the difference between this (in C# - you haven't specified which language you're interested in):

class Form : Document { ... }

// Later on
Controls.Add(new DocumentDisplay(form));

and this:

class Form
{
    private Document Document { get; set; }
    // Other stuff
}

// Later on
Controls.Add (new DocumentDisplay(form.Document));

Without knowing the rest of your design, it's hard to recommend one or the other. I usually prefer composition over inheritance, but this feels like more of a natural inheritance situation.

Jon Skeet
Yes, i have code that is the same for any document, getters and setters. For now the purpose is read-only
Martijn
It's not a case of whether the *implementing* code is the same. It's whether you have code which is meant to be able to *use* any document type.
Jon Skeet
I don't get the last part. What do yo9u mean by "to be able to use any document type"?
Martijn
Editing the answer to say what I mean...
Jon Skeet
Do you have functionality that works on any type of document e.g. Print( obAnyTypeOfDocument ) which should work irrespective of whether it is a Form, WorkInstruction, Procedure, etc.
Gishu
@Gishu: yes The purpose of the objects is to print data
Martijn
A: 

The old school answer would be creating a class with the shared fields and inherit.

The trendy answer would be to create a class that has those fiends and have it as a member.

Inheriting creates more dependency between the classes, if you will every change the base, which is considered bad practice.

In a simple case it doesn't really make that much difference. But if you start adding behavior to those fields it may.

n-alexander
A: 

Too little information to give a definitive answer

If the only thing these objects share is data attributes... I'd use something like this.

class Document
{
   List<Field> m_Fields;
   public void AddField(Field f) {... }
   public void AddFields(Field[] f) {... }
}

class DocumentFactory()
{
  public static Document GetDocument()
  {
     Document d = new Document();
     d.AddFields(GetDocumentFields());   // private helper .. returns fields 1-8
     return d; 
  }
  public static Document GetForm()
  {
     Document d = new Document();
     AddDocumentFields(d);
     d.AddField(FIELD_9);
     d.AddField(FIELD_10);
  }
  // and so on..
}

Any code that works irrespective of type of document, goes into the Document class.
If in addition to this you have behavior that is specialized/based on specific object type, you'd need to grow an inheritance type-hierarchy (as Jon says.. it looks like a IS-A relationship from the names.)

Gishu