www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Structuring classes with similar properties

reply Nathan Petrelli <npetrelli klassmaster.com> writes:
I didn't knew where to post this questions, please excuse me if this isn't the
right group.

I'm having problems organizing the code of my application because I have
several similar classes but some of them lacks some properties and others
introduce new properties. Right now they all have lots and lots of duplicated
code and it's started to hurt development:

class Invoice {
	int id;
	char[] code;
	char[] clientName;
	real total;
	real payment;
	InvoiceDetails[] details;
}

class Call {
	int id;
	char[] clientName;
	char[] phone;
	real total;
	CallDetails[] details;
}

class Quote {
	int id;
	char[] clientName;
	real total;
	real payment;
	QuoteDetails[] details;
}

// There are other four like this.

Each class also has similar operations, but they all have to cope with a class
having some set of properties and different set of properties in another:

class Invoice {
	string save() {
		// ...
		row.code = generateCode();
		row.total = calculateTotal(details);
		row.save(this);
	}
	string print() {
		printer.appendCenter("%s", toString(getUTCTime()));
		printer.append("Code: %s", code);
		printer.append("Client: %s", clientName);
		foreach (InvoiceDetails det; details)
			printer.append("%s %s %s %s", det.product, det.ammount, det.price);
		printer.append("Total: %s", total);
		printer.print();
	}
	// ...
}

class Call {
	string save() {
		// ...
		row.phone = phone;
		row.total = calculateTotal(details);
		row.save(this);
	}
	string print() {
		printer.appendCenter("%s", toString(getUTCTime()));
		printer.append("Client: %s", clientName);
		printer.append("Phone: %s", phone);
		foreach (CallDetails det; details)
			printer.append("%s %s %s %s", det.product, det.ammount, det.price);
		printer.append("Total: %s", total);
		printer.print();
	}
	// ...
}

As you can see, I have a problem. A big problem. ;)

The the typical solution of using inheritance and calling the super class'
methods to add something before or after doesn't work here because the changes
on the operations happen in the middle of methods.

So my question is: How would you structure code like this?

Thanks
Mar 03 2007
next sibling parent "Antti Holvikari" <anttih gmail.com> writes:
On 3/3/07, Nathan Petrelli <npetrelli klassmaster.com> wrote:
 I didn't knew where to post this questions, please excuse me if this isn't the
right group.

 I'm having problems organizing the code of my application because I have
several similar classes but some of them lacks some properties and others
introduce new properties. Right now they all have lots and lots of duplicated
code and it's started to hurt development:

 class Invoice {
         int id;
         char[] code;
         char[] clientName;
         real total;
         real payment;
         InvoiceDetails[] details;
 }

 class Call {
         int id;
         char[] clientName;
         char[] phone;
         real total;
         CallDetails[] details;
 }

 class Quote {
         int id;
         char[] clientName;
         real total;
         real payment;
         QuoteDetails[] details;
 }

 // There are other four like this.

 Each class also has similar operations, but they all have to cope with a class
having some set of properties and different set of properties in another:

 class Invoice {
         string save() {
                 // ...
                 row.code = generateCode();
                 row.total = calculateTotal(details);
                 row.save(this);
         }
         string print() {
                 printer.appendCenter("%s", toString(getUTCTime()));
                 printer.append("Code: %s", code);
                 printer.append("Client: %s", clientName);
                 foreach (InvoiceDetails det; details)
                         printer.append("%s %s %s %s", det.product,
det.ammount, det.price);
                 printer.append("Total: %s", total);
                 printer.print();
         }
         // ...
 }

 class Call {
         string save() {
                 // ...
                 row.phone = phone;
                 row.total = calculateTotal(details);
                 row.save(this);
         }
         string print() {
                 printer.appendCenter("%s", toString(getUTCTime()));
                 printer.append("Client: %s", clientName);
                 printer.append("Phone: %s", phone);
                 foreach (CallDetails det; details)
                         printer.append("%s %s %s %s", det.product,
det.ammount, det.price);
                 printer.append("Total: %s", total);
                 printer.print();
         }
         // ...
 }

 As you can see, I have a problem. A big problem. ;)

 The the typical solution of using inheritance and calling the super class'
methods to add something before or after doesn't work here because the changes
on the operations happen in the middle of methods.

 So my question is: How would you structure code like this?
Break your methods to smaller pieces and use inheritance :-) -- Antti Holvikari
Mar 03 2007
prev sibling parent Knud Soerensen <4tuu4k002 sneakemail.com> writes:
On Sat, 03 Mar 2007 14:02:07 -0500, Nathan Petrelli wrote:

 I didn't knew where to post this questions, please excuse me if this isn't the
right group.
 
I think digitalmars.D.learn would be better.
 I'm having problems organizing the code of my application because I have
several similar classes but some of them lacks some properties and others
introduce new properties. Right now they all have lots and lots of duplicated
code and it's started to hurt development:
 
First notice that your classes contain an abstract class I would call a ClientServiceRequest. class ClientServiceRequest { int id; char[] clientName; real total; Details[] details; string print() { printer.appendCenter("%s", toString(getUTCTime())); printpart1(printer); // must be implemented in the child class printer.append("Client: %s", clientName); printpart2(printer); // must be implemented in the child class foreach (Details det; details) printer.append("%s %s %s %s", det.product, det.ammount, det.price); printer.append("Total: %s", total); printer.print(); } }
Mar 03 2007