473,395 Members | 1,377 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Help with class design

I come from a Delphi background, and am currently trying to port or convert
some of our Delphi classes to C#. I've got a good handle on basic class
design, but am a bit lost with some of the more advanced things I need to
do, and was hoping somebody could point me to an online resource that can
help me better understand what I need to do.

For example, one of the classes is a Shipment class. A Shipment can have
any number of Packages, so I have designed a Shipment Class and a Package
class. I should be able to retrieve any of the packages by it's index or I
should be able to use a single package as a property. For example (these
examples are not working code, merely pseudo-code to demonstrate what I
need):

oShip = new Shipment();
oShip.AddPackage(sPackageID, dPackageWeight);
oShip.AddPackage(sDifferentPackageID, dPackageWeight);

// access the first package object in the shipment
MessageBox.Show(oShip.Packages[0].PackageID);

// loop though all packages
foreach(Package oPack in oShipment)
{
MessageBox.Show(oPack.PackageID);
}

Either a basic template that shows how I need to design my class or a good
online resource would be greatly appreciated!

TIA!
Nov 17 '05 #1
6 1465
J... The Shipment class probably should not expose its internal data
like that. In other words, I would not allow an external caller to
access the Package collection in the Shipment directly. I would add a
level of indirection here, Properties for instance. Internally, the
Shipment class can store the Packages in a private array or in a
private, type safe collection derived from collection base. Externally,
the Shipment can provide get accessors (by index and/or key) or return a
read only collection or a copy of the internal array so the caller has
access to the individual packages but not to the private internal
collection in the shipment object. You can then add set accessors (Add,
Remove) that validate any attempt to modify the contents of the internal
collection.

Regards,
Jeff
// loop though all packages
foreach(Package oPack in oShipment)
{
MessageBox.Show(oPack.PackageID);
}
*** Sent via Developersdex http://www.developersdex.com ***
Nov 17 '05 #2
"JSheble" <js************@logicor.com> a écrit dans le message de news:
#K*************@TK2MSFTNGP15.phx.gbl...
I come from a Delphi background, and am currently trying to port or convert some of our Delphi classes to C#. I've got a good handle on basic class
design, but am a bit lost with some of the more advanced things I need to
do, and was hoping somebody could point me to an online resource that can
help me better understand what I need to do.
There really is no difference in how you would design classes in C# as
opposed to Delphi. If you got the design right in Delphi, then it should be
fine in C# :-)
For example, one of the classes is a Shipment class. A Shipment can have
any number of Packages, so I have designed a Shipment Class and a Package
class. I should be able to retrieve any of the packages by it's index or I should be able to use a single package as a property. For example (these
examples are not working code, merely pseudo-code to demonstrate what I
need):
You need to start off by asking yourself whether a Package can exist outside
of a Shipment e.g. can a Package be stored in a Warehouse or transported in
a DeliveryVehicle.

If a Package can exist outside of a Shipment then the relationship between
them is one of Aggregation and can be expressed thus :

class Package
{
...
}

class PackageList
{
void Add(Package item)...
void Remove(Package item)...
Package this[int idx]...
...
}

class Shipment
{
PackageList Packages
{
get {...}
set {...}
}
}

But if the Packages cannot exist outside of a Shipment then the relationship
is one of Composition and should be expressed thus :

class Package
{
...
}

class Shipment
{
Package AddPackage()...
void RemovePackage(Package item)...
int PackageCount
{
get {...}
}...
PackageEnumerator GetPackageEnumerator()...
...
}

The essential difference is that the Composition relationship should not
allow adding or otherwise manipulating Packages without going through
methods of the Shipment.
oShip = new Shipment();
oShip.AddPackage(sPackageID, dPackageWeight);
oShip.AddPackage(sDifferentPackageID, dPackageWeight);
PAckageWeight should be a property of the Package class and you should not
need to pass such details to the Add method of the Shipment class. Assuming
you are using Composition, you should retrieve a new instance of the Package
class from the Shipment and set properties like Weight, etc on that
instance. I suspect though that you should be using Aggregation and
therefore you should create an instance of Package, set the properties
either in the constructor or otherwise, and then add the instance to the
Shipment.
// loop though all packages
foreach(Package oPack in oShipment)
{
MessageBox.Show(oPack.PackageID);
}


I am not sure whether you really should make the Shipment 'enumerable', that
implies it not really much more than a list ??

Joanna

--
Joanna Carter (TeamB)
Consultant Software Engineer
Nov 17 '05 #3
Ok, so assuming a package cannot exist outside of a shipment, I would be
using the Composition type. In reality, a package could exist outside of a
shipment in the real world, but for this object model, it makes no sense to
have a package without a shipment.

But this line of pseudo-code you added:

PackageEnumerator GetPackageEnumerator()...

makes no sense to me. I'm assuming I will have to create a
PackageEnumerator type? Which should have or do what exactly?

I don't suppose you'd have a small example class showing or demonstrating
this, would you? Once I see and digest an example, hopefully I'd be able to
simulate it for my specific needs.
PAckageWeight should be a property of the Package class and you should not
need to pass such details to the Add method of the Shipment class.
Assuming
you are using Composition, you should retrieve a new instance of the
Package
class from the Shipment and set properties like Weight, etc on that
instance.
Actually, a package cannot exist without a weight, which is why I'm adding
it to the Addpackage method. A package must have a package ID and a weight.
If not, there's no sense in adding a package. I think leaving the weight as
a parameter is a feasible solution.

"Joanna Carter (TeamB)" <jo*****@nospamforme.com> wrote in message
news:%2****************@tk2msftngp13.phx.gbl... "JSheble" <js************@logicor.com> a écrit dans le message de news:
#K*************@TK2MSFTNGP15.phx.gbl...
I come from a Delphi background, and am currently trying to port or

convert
some of our Delphi classes to C#. I've got a good handle on basic class
design, but am a bit lost with some of the more advanced things I need to
do, and was hoping somebody could point me to an online resource that can
help me better understand what I need to do.


There really is no difference in how you would design classes in C# as
opposed to Delphi. If you got the design right in Delphi, then it should
be
fine in C# :-)
For example, one of the classes is a Shipment class. A Shipment can have
any number of Packages, so I have designed a Shipment Class and a Package
class. I should be able to retrieve any of the packages by it's index or

I
should be able to use a single package as a property. For example (these
examples are not working code, merely pseudo-code to demonstrate what I
need):


You need to start off by asking yourself whether a Package can exist
outside
of a Shipment e.g. can a Package be stored in a Warehouse or transported
in
a DeliveryVehicle.

If a Package can exist outside of a Shipment then the relationship between
them is one of Aggregation and can be expressed thus :

class Package
{
...
}

class PackageList
{
void Add(Package item)...
void Remove(Package item)...
Package this[int idx]...
...
}

class Shipment
{
PackageList Packages
{
get {...}
set {...}
}
}

But if the Packages cannot exist outside of a Shipment then the
relationship
is one of Composition and should be expressed thus :

class Package
{
...
}

class Shipment
{
Package AddPackage()...
void RemovePackage(Package item)...
int PackageCount
{
get {...}
}...
PackageEnumerator GetPackageEnumerator()...
...
}

The essential difference is that the Composition relationship should not
allow adding or otherwise manipulating Packages without going through
methods of the Shipment.
oShip = new Shipment();
oShip.AddPackage(sPackageID, dPackageWeight);
oShip.AddPackage(sDifferentPackageID, dPackageWeight);


PAckageWeight should be a property of the Package class and you should not
need to pass such details to the Add method of the Shipment class.
Assuming
you are using Composition, you should retrieve a new instance of the
Package
class from the Shipment and set properties like Weight, etc on that
instance. I suspect though that you should be using Aggregation and
therefore you should create an instance of Package, set the properties
either in the constructor or otherwise, and then add the instance to the
Shipment.
// loop though all packages
foreach(Package oPack in oShipment)
{
MessageBox.Show(oPack.PackageID);
}


I am not sure whether you really should make the Shipment 'enumerable',
that
implies it not really much more than a list ??

Joanna

--
Joanna Carter (TeamB)
Consultant Software Engineer

Nov 17 '05 #4
The package collection has to be available through the Shipment object.
Accessing it via oSHipment.Packages[iPkg].SomePackageProperty is the
desirable method for accessing individual packages or through an enumerator.

"Jeff Louie" <je********@yahoo.com> wrote in message
news:OP**************@TK2MSFTNGP12.phx.gbl...
J... The Shipment class probably should not expose its internal data
like that. In other words, I would not allow an external caller to
access the Package collection in the Shipment directly. I would add a
level of indirection here, Properties for instance. Internally, the
Shipment class can store the Packages in a private array or in a
private, type safe collection derived from collection base. Externally,
the Shipment can provide get accessors (by index and/or key) or return a
read only collection or a copy of the internal array so the caller has
access to the individual packages but not to the private internal
collection in the shipment object. You can then add set accessors (Add,
Remove) that validate any attempt to modify the contents of the internal
collection.

Regards,
Jeff
// loop though all packages
foreach(Package oPack in oShipment)
{
MessageBox.Show(oPack.PackageID);
}
*** Sent via Developersdex http://www.developersdex.com ***

Nov 17 '05 #5
I see. My bad.
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
Package p1= new Package(21);
Package p2= new Package(35);
Shipment s1= new Shipment();
s1.Add(p1);
s1.Add(p2);
for (int i=0; i<s1.Count;i++)
{
System.Console.Write(s1.GetPackage(i).ID+":");
System.Console.WriteLine(s1.GetPackage(i).Weight);
}
foreach(Package p in s1)
{
System.Console.Write(p.ID+":");
System.Console.WriteLine(p.Weight);
}
System.Console.ReadLine();
}

public class Package : IPackage
{
// static stuff
private static int uniqueID= 0;
private static int GetUniqueID()
{
lock(typeof(Package))
{
return uniqueID++; // returns zero at start
}
}

private int weight= 0;
private int id;

public Package(int weight)
{
this.id= Package.GetUniqueID();
if (weight > 0)
{
this.weight= weight;
}
}
#region IPackage Members
...
Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Nov 17 '05 #6
"JSheble" <js************@logicor.com> a écrit dans le message de news:
er**************@TK2MSFTNGP10.phx.gbl...
Ok, so assuming a package cannot exist outside of a shipment, I would be
using the Composition type. In reality, a package could exist outside of a shipment in the real world, but for this object model, it makes no sense to have a package without a shipment.
I still have my doubts about using Composition, but for the sake of example,
let's continue...
But this line of pseudo-code you added:

PackageEnumerator GetPackageEnumerator()...

makes no sense to me. I'm assuming I will have to create a
PackageEnumerator type? Which should have or do what exactly?
This just needs to implement IEnumerator; two methods : Reset(), MoveNext()
and one property : Current.
PAckageWeight should be a property of the Package class and you should not need to pass such details to the Add method of the Shipment class.
Assuming
you are using Composition, you should retrieve a new instance of the
Package
class from the Shipment and set properties like Weight, etc on that
instance.


Actually, a package cannot exist without a weight, which is why I'm adding
it to the Addpackage method. A package must have a package ID and a

weight. If not, there's no sense in adding a package. I think leaving the weight as a parameter is a feasible solution.


Assuming you are using Composition, then your method that takes two
parameters would be sensible.

Joanna

--
Joanna Carter (TeamB)

Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
Nov 17 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Sacha | last post by:
I work on a rather large C++ project. The design, so far, seems to be fine. However, there is one class, where the number of methods (and less dramtically the number of members, too) is growing and...
7
by: Dan Trowbridge | last post by:
He everyone, I am just getting started with .NET and I am having a porting problem. I get and error in code that lookssomething like this (really stripped down but you get the idea)... class...
8
by: Martin Horn | last post by:
Hi, I am trying to add extra functionality to the standard RichText control, but I've fallen at the first hurdle,can someone take a look at the following code and tell me why it fails to return...
4
by: Brian | last post by:
Hello.. After many books and self study, I think I am finally starting to grasp the basics of classes. However, I can't quite grasp how to use them after I design them. For example, I want to...
2
by: Carlo, MCP | last post by:
Hi, Sorry for posting twice, but I hope in your comprehension. Please help me! I'm troubling from months with a serious serialization problem that I'm not able to solve. I try to describe as...
1
by: stalinmaddy | last post by:
I have problem with layers in my code. The problem is that it works well with ordinary html files but when include with any other files which have flash script or more javascript it doesn't...
5
by: aaragon | last post by:
Hello everybody, I appreciate your taking the time to take a look at this example. I need some help to start the design of an application. To that purpose I'm using policy-based design. The...
53
by: Hexman | last post by:
Hello All, I'd like your comments on the code below. The sub does exactly what I want it to do but I don't feel that it is solid as all. It seems like I'm using some VB6 code, .Net2003 code,...
4
by: Andrew Taylor | last post by:
Hi, I've been using PHP for a long time, I have designed and developed a number of mid-range systems. I've always used a procedural approach. I fully understand the concept of OO, I know all the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.