|
-
Jul 31st, 2010, 12:14 PM
#1
Thread Starter
Addicted Member
[RESOLVED] Inheritance and copy/use of member instances
Hi,
A very basic question:
If I declare and instantiate an instance of class B within class A, how do I make instances of class A member objects/variables accessible from class B?
Last edited by bretddog; Jul 31st, 2010 at 01:11 PM.
-
Jul 31st, 2010, 01:06 PM
#2
Fanatic Member
Re: Inheritance and copy/use of member instances
SOmeone is bound to come along and tell me where I get this wrong, so possibly I will learn something here as well.
In order for an instance of contained class B to access properties of an instance of containing class A, and assuming B inherits A. Hmmm.
If B inherits A, you could set the corresponding properties of B after intiialization, and then tie the property Getters and Setters of Class A to the corresponding Propertyies on contained class B.
Or, of course, you could try initializing Class B by passing a parameter in with a reference to A. However, this, to me, would constitute a circular reference, and while I believe you get away with it in .NET due to the GC, I suspect it is poor programming practive.
Why do you want to create a class structure like this? It seems like you might want to examine the design of your inheritance hierarchy, and consider using containment instead of inheritance.
Problems like this are probably indicative of a fundamental structural flaw . . .
-
Jul 31st, 2010, 01:23 PM
#3
Re: Inheritance and copy/use of member instances
Why assume that B inherits A? The OP didn't mention that, and it would make for a really bizarre situation, since A has a B, which inherits from A, so it has all the properties of an A.
The way you posted this, there is no clear way for B to access A. B is a member of A, but has no knowledge of A, intrinsically, nor should it. If B is a stand alone class, as it should be, then it should not be dependent on the existence of any other class. Therefore, for it to be aware of any part of A, then A would have to be passed in to B as an argument to a method. It is uncommon, but not at all unheard of, to have A have a B, which is passed A as part of its constructor. This would allow B to access A, and A to access B.
My usual boring signature: Nothing
 
-
Jul 31st, 2010, 02:03 PM
#4
Thread Starter
Addicted Member
Re: Inheritance and copy/use of member instances
Thanks! 
Yes you are both correct. I did say B inherits A, but edited, as i thought nobody had answered here.. But ok..
Problems like this are probably indicative of a fundamental structural flaw . . .
Indeed... very true. I start to understand now slowly.. 
It is uncommon, but not at all unheard of, to have A have a B, which is passed A as part of its constructor.
This is what I'm doing now after realizing my poor code practice. Hmm.. still you say it's uncommon.. Means I probably still should improve/change my fundamental structure..
Let me think a few minutes...
-
Jul 31st, 2010, 03:40 PM
#5
Fanatic Member
Re: Inheritance and copy/use of member instances
 Originally Posted by Shaggy Hiker
Why assume that B inherits A? The OP didn't mention that, and it would make for a really bizarre situation, since A has a B, which inherits from A, so it has all the properties of an A.
The way you posted this, there is no clear way for B to access A. B is a member of A, but has no knowledge of A, intrinsically, nor should it. If B is a stand alone class, as it should be, then it should not be dependent on the existence of any other class. Therefore, for it to be aware of any part of A, then A would have to be passed in to B as an argument to a method. It is uncommon, but not at all unheard of, to have A have a B, which is passed A as part of its constructor. This would allow B to access A, and A to access B.
@SHaggy - He ORIGINALLY stated B inherited A. Then he edited his post . . .
I was astounded at my lack of perception, until I saw the OP's post above regarding editing that part out. I KNEW I wasn't THAT off balance!
Re:
Quote:
It is uncommon, but not at all unheard of, to have A have a B, which is passed A as part of its constructor.
This is what I'm doing now after realizing my poor code practice. Hmm.. still you say it's uncommon.. Means I probably still should improve/change my fundamental structure..
I am guessing at Shaggy Hiker's context here, but I am betting he means it is uncommon to pass a reference to B in the constructor of A. It is not uncommon AT ALL for Class a to contain an instance of Class B. This is very common. However, it DOES increase the dependency between classes (What they call "tight coupling" in OOP terms, I think.).
If you have a class A which contains a Class B, it would not be at all unusual to have a property or Method defined on the public interface of A which allows access to B. Depending on how B is being used, you might define this as a general Property, a ReadOnly Property (If initialization of B is accomplished entirely within A), or a Method (SUb or function).
The unusual but not unheard of part would be initializing B as a part of the constructor of A.
I am imagining Shaggy might have some interesting feedback on this. He may even correct me on a few things. However, it sounds like you have made progress if you have done away with the inheritance in this case!
Please keep us posted on your progress . . .
-
Jul 31st, 2010, 05:58 PM
#6
Re: Inheritance and copy/use of member instances
 Originally Posted by RunsWithScissors
@SHaggy - He ORIGINALLY stated B inherited A. Then he edited his post . . .
I was astounded at my lack of perception, until I saw the OP's post above regarding editing that part out. I KNEW I wasn't THAT off balance!
 
Yeah. I read that OP about three times trying to figure out why you were assuming that there was inheritance.
As for the references, while I said that it was uncommon, I didn't mean to suggest that it is a bad practice. I am using it myself in a few cases. It is very common for one class to have a second class as a member. It is not typically the case that the contained class needs access to the container class, but if that is the case, then go ahead and provide it. If B always needs to have access to an instance of A, then I would be passing the A to the B in the constructor for B. That way, B always knows which instance of A to use.
In this case, A happens to contain an instance of B as a member, and that's fine.
The one thing I would consider is what the actual relationship between A and B is. If every B absolutely has to have an A, and every A absolutely has to have a B, perhaps there should just be one class C that contains the functionality of both the A and the B. On the other hand, it could be the case that A has a B, but the instance of B changes over the lifetime of A, such that the B that the A starts out with is replaced with a new one. In that case, then certainly the B has to be a member of A, and has to be passed the A in its constructor.
Another situation where passing in the A makes sense is if there is more than one B in A. I'm using that type of construct at the moment, where A holds a List (of B), but every B in the list requires a reference to A, and therefore, whenever a New B is added to the list, it is given A as an argument to the constructor.
Keep in mind that when you pass A as an argument to the constructor, all you are really passing is the memory address of the A object. In other words, all you are passing is a four or eight byte integer, which allows B to access A, but is quite light weight.
My usual boring signature: Nothing
 
-
Jul 31st, 2010, 06:55 PM
#7
Thread Starter
Addicted Member
Re: Inheritance and copy/use of member instances
Thanks guys! really helpful.. 
Let me give a bit more details of my program, maybe I haven't even managed to describe correctly yet.. (Forget about above references A, B)
Class A: MainBLL class
Class B: clientObject class (2-way communication with other program)
Class C: OrderDetails class
A: Program lifespan, member of the Form class
B: Program lifespan, member of A
C: Short-lifetime local member of a method in A
So far ok.. Then how do I send an order? (must send via the B object) In this case I see three solutions:
1. Put send logic inside C. Then I must pass B to C, as B is the object that is used to send data.
2. Put send logic inside A. Then it's already ok, we can return objects from C to A, that B object can send.
3. Put send logic in separate class D:
Class D: SendOrder class (short-lifetime member of method A)
Eh.. I don't really know what of these to chose. I tend to want to do 3), as this looks to be most separation, which I feel is probably good as my program expands. But if so, shall D be a local member of A, or a local member of C? If the latter, then I must pass B from A to C, then to D, in order send data. That seems a bit stupid (?). So I guess it's better for A to request the details from C, via a public "GetOrderDetails" function (in C). Then pass this data, plus the B object, as parameters into D, to send. Probably pass it in the constructor.
Hope that is easy to understand. It seems logical for me now to do like this. But maybe you see better solution.. ?
-
Jul 31st, 2010, 07:26 PM
#8
Fanatic Member
Re: Inheritance and copy/use of member instances
If I understand you correctly:
Class A: MainBLL class is declared and used within a form, and is your business logic component?
Class B: clientObject class (2-way communication with other program) 'Is essentially the API for another app?
Class C: OrderDetails class Is the information captured from the form, and now needs to be sent to the other application via Class B?
In that case, You could use either option 2 or 3. Which way you go would depend upon how complex your code is to perform the send via Class B. If it is a simple method call on an instance of B with some parameters consisting of the data you need to send, you might as well just do it as a method of Class A.
If, on the other hand, there are complex transformations or other logic required to render the data compatible with Class B, you MIGHT create a separate class to do so, if only for the purpose of encasulating that code for re-use, and to potentially simplify maintenence.
The result of such an approach would be maintaining object simplicity at the cost of increased project complexity.
This feels like one of those areas where there is no right or wrong way - in the end it is a judgement call on your part. And you may find later that, whichever approach you took, the OTHER way now makes more sense. In that case, you can always re-factor to suit.
I would probably start by putting the SendOrder method as a Method on Class A. Then, if it looked complicated, and might be code that I need to maintain (or even better, if SOMEONE ELSE needs to maintain), I would examine moving it to it's own class.
Hope that made sense . . .
RWS
-
Jul 31st, 2010, 10:55 PM
#9
Re: Inheritance and copy/use of member instances
Without knowing more about the code, it isn't certain, but I would suggest that you may have left out an option. If B is the object that sends and receives, then the send logic should be in B, and B should have a method that takes a C and sends it.
As an example, I have a bunch of robot code that sends everything back and forth via UDP packets. Each program has a whole bunch of stuff, often including a form, which could act like you object A. Each program also has a single instance of my UDP class which handles all listening and sending operations. If I want to send a class out from a program, I serialize the class into an array of bytes and pass that array to the UDP class, and the UDP class sends the data. In that case, the UDP class acts like your description of your class B. In my case, the only thing that it ever sends is an array of bytes. In your case, you might have different Send methods in B that takes different types of arguments to send different things.
Still, if B does the communication, then it should be responsible for all sending and receiving, as that is what communication consists of.
My usual boring signature: Nothing
 
-
Aug 1st, 2010, 04:49 AM
#10
Thread Starter
Addicted Member
Re: Inheritance and copy/use of member instances
Runwithscissors, ShaggyHiker;
Yes you make very good sense, and strengthen my otherwise somewhat unconfident understanding.
You are correct about the details of my classes;
Class B is the connection object of a C# wrapper library of an API. So it's a layer between the API and my code that makes my use of the API easier.
This ClientObject (B) raises a number of events that A listens to (Addhandler...), and I send/request data through public methods of B. Hence B is a class that I don't change, as it's part of a library, I just use it.
I will send data in various ways, some complex with data verification logic etc, and some more simple. So most of the time I think option 3 will be best, as I like to keep my A class as clean and short as possible, and my code will grow a lot. I don't have to think about other programmers, as it's just for my personal use.
I may even have many steps in this process:
1. Create order details
2. Verify order details with set permissions etc.
3. Send order
4. Listen for incoming verification of order status.
5. Log success or alert on error.
One thing that is important is that I may (later potentially) want to change the API wrapper library, to another library. This is something I want to respect in my code. So I kind of want to keep separation to the rest of my code. I'm not entirely sure how to do this yet. Perhaps it means I should actually be as dramatic as to remove B as a member of A, and instead make a separate ClientCom class that has B as a member, and act as simply a communication layer. Then, if I later change the API wrapper library, I may only need to edit my ClientCom class. Not sure if I will do this though. Just would like to know what are sensible ideas, so that I can think of it as I program along.
One problem with this though, is the events that are raised by the ClientObject. If I put B as member of a separate ClientCom class I will have to forward (?) all events raised by it. Maybe it's not worth it. Communication is really a core feature of the program. But while I can filter out the communication logic, I still use some other classes of the library in my code also. Although that is just object structure. hmmmm..... yes.. I think perhaps the fact that I use a library, means I must of course accept that my code is dependent on this library (Both my MainBLL, and several of my other classes). So probably it's more sensible to keep B in A still...
I will have to think a bit about this one... I think I may be going a bit too far here, and should keep B in A, so the events B raise will be easily available to A, but still to refacture my "send data" logic to one class, or to a set of classes that are separate from my other logic.
PS: Just to give the right overview/perspective;
I also have a "userConnection", that is a connection I have programmed myself that accepts connection by several instances of another program. So my program acts as a type of data-hub, in lack of better words. But also with verification/permission checking of everything the user applications try to perform. And also logging of all activity. So it's one connection to API, and multiple connections to "user apps". (I try to discuss in general terms and not reveal too much details, as it makes discussion and understanding of concepts easier, at least for me)
Last edited by bretddog; Aug 1st, 2010 at 07:19 AM.
-
Aug 1st, 2010, 10:00 AM
#11
Re: Inheritance and copy/use of member instances
What you say sounds reasonable. However, let me describe something I am working on, as it may give you other ideas:
In a project I am working on, there will be a main form and a few other classes. There will also be an unknown number of dlls which are plug-in components that others (or myself) can write at a later date. Heck, I don't even know what will be needed, at this point. The problem I ran into was that these plug-in modules need to be able to communicate back to the main form. They may even need to communicate some information to other classes in the main project, or even with other modules, but they certainly have to communicate with the main form. So how do I do that?
Early on, I realized that much of the communication makes most sense if it is done via events. I could have created an interface that would be implemented by the objects in the plug-in modules (and the main module) such that a method could be called on each interface whenever any communication was necessary, but that would be overly complicated, especially when considering that the majority of the modules really won't ever communicate with anyone else. Events work roughly the same way, except that they are 'on demand'. The object that raises the event keeps a list of the methods it needs to call when the events are raised, and each module that wants to be called subscribes to the object. Therefore, by using events, it would be just what I wanted, because all those who want to be called will be, and the rest won't be.
The next question was who should be raising the events? Clearly, the main form needed to raise plenty of events, and other modules might also want to raise events, and all would want to subscribe to some events. Therefore, it looked like it should be the main form that is raising the events, but for the modules to subscribe to those events, they would have to have a reference to the main form. That's not good. If they have a reference to the main form, then they have access to ALL the public methods of that main form, and there are plenty of things they should not have access to.
Therefore, I created an EventRaiser class. This is a pretty small class that has a series of events that can be raised, and a series of public methods that raise those events. The main form creates an instance of this class when it is created (and there will only be one main form, so there will be only one instance of the EventRaiser class in the program). As any object is created in any of the modules (dlls), it is passed this instance of the EventRaiser class. Therefore, there is only one instance of the EventRaiser, but all objects hold a reference to it. This means that any object can raise an event through this object, and that event can be handled by any other object in the program.
My usual boring signature: Nothing
 
-
Aug 1st, 2010, 05:49 PM
#12
Thread Starter
Addicted Member
Re: Inheritance and copy/use of member instances
Very interesting idea... I will keep in mind.
I do use events, as my API (library) communicates incoming data by raising events. Also the user connections raise events on incoming data. They are all socket connections (TcpClient). However I'm somewhat reluctant to introduce further events to solve logic, as I'm imagining it could cause some random errors by threads not executing in the expected/wanted order. However I don't really know if this is a valid concern, and probably depend on my logic I guess, if it's a problem or not. Currently I'm handeling all form/control events by calling public methods in my MainBLL class, and so far that is fine (in this case), as I have really no other local components.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|