Click here to Skip to main content
15,881,139 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I'm an amateur programmer. I sell online in various forums and write my own software to help with sales processing. So say I have a SQL database that has a customer table in it called SQL.Customer. If I make a sale online I can download a feeBay.Customer object with pretty much the same info as SQL.Customer. If the customer pays with feePal I can download a feePay.Customer object, again with pretty much the same info.

My problem is that I need to pass customer info around. For example, I download a feeBay customer, check the database to see if the customer is new, check feePal to see if the addresses match, etc. But since they are all different types converting from one to another (and back) is a pain.

I would think this is a common type of problem. It seems that every time I run into something like this I handle it a different way. Is there a standard design pattern/procedure/architecture to handle different unrelated objects which contain mostly the same information?
Posted

I would say SA's approach is correct in general. However if you cannot change the object types in question because the definitions belong to someone or something else then you have a slightly different problem.
In this case I would use a form of mediator object which 'pretends' to be the type you want but is actually your own object which can store the set of all data from both types. In other words use one type that has two interfaces, one interface matching each of the types you need to manage but stores the data internally in its own way. You'll need an extra BehaveAs() function to tell it which type to 'pretend' to be if there are overlaps or inconsistencies between them.
This is fine for types with pure function interfaces, i.e. no public data members. If the types involved have public data members then it's not so easy, the first step is to go over fully to smart pointers so you always only access such public data members through another object. Then a special smart pointer can be used which can actually point to 2 things and has a BehaveAs() function to tell it which one to use.
Putting all this into code would require a whole article and a lot of time so I hope the compressed English explanation is useful.
 
Share this answer
 
Comments
Dell.Simmons 2-Feb-13 19:23pm    
Thanks for the response. Yes, the object types are not up to me, I have to deal with what I am sent. I'd been wondering if I could use Interfaces some way, I'll give your 'mediator object' idea some thought. Thanks again
Sergey Alexandrovich Kryukov 2-Feb-13 19:36pm    
Good point, and one of the possible approaches, my 5.

I did not argue with OP against "changing the object types", because I don't think OP tried to do that. You are right about it, but I'm sure OP complained about different thing, a need for "conversion", which simply means "cloning" (memberwise) data from an object of one type to another. This is usual for pre-OOP approach with structures, and of course would be a big abuse in OOP word.

—SA
Matthew Faithfull 2-Feb-13 19:49pm    
Yes, these things tend to crop up at the edges of systems where a nice OOP design has to interface with the real sometimes messy world including old pre-OOP systems. The approach in principle is to wrap the messiness up to make it look like OOP rather than to break open the objects to make them work with the mess. The details however always come down to the specific situation. I just happen to have dealt with quite a few similar situations.
What you say is a bright example of anti-OOP thinking. You don't need to convert from one type to another.

First of all, despite of having some different properties of different customers, they have a lot in common, such as address, name, some kind of unique ID, etc. This should be put in some abstract base type and used regardless of the customer type.

Other things should be expressed as virtual functions. Do you know this thing, a heart of OOP? Do you understand late binding? If not, it's hard to explain in full in a short answer, but the idea is that some method in a base class can call some abstract method, despite the apparent fact that it is not implemented. In a run-time type inherited from your base type, the call will be substituted with the call to the overridden method, closest to the run-time type. In real life, of course, nothing is "substituted", as such calls are done via a "virtual method table". In this way, some method general in signature but different in implementations, can be called in abstract base type, but the late bound method is called during run time. In other words, you don't know what exactly implementation will be called at the point of the call; it will be found when a concrete run-time types is used.

This mechanism should give you a powerful abstraction weapon.

I want to warn you in advance: if you ask how to learn OOP and even OOD, my answer will be: learn the fundamentals from scratch; this is not a place to teach them. But let me tell you: if you don't learn OOP fundamentals very well, you can do nothing in the field you describe.

Unfortunately, it might not be as simple as that. You night need two (or more) unrelated hierarchies: for example, one deal with payments, another with options of the products you sell. While it would be the best to avoid such situation, it may be needed in real life. There are different approach to this problem: multiple inheritance, aggregation, interfaces (more exactly, implementation of multiple base interfaces, which is sometimes called weak form of multiple inheritance).

If you are educated enough in OOP (I questioned that, but in fact I an not sure about it, may be you are), read my article on the topic, where I put forward my own approach to parallel hierarchies, among other things: Dynamic Method Dispatcher[^].

—SA
 
Share this answer
 
Comments
Dell.Simmons 2-Feb-13 19:20pm    
Thanks for your response. I appreciate what you are saying, but apparently I was not clear. I do have to convert from one type to the other. Each customer object is defined by the web service that sends them to me(feeBay, feePal, etc). Customer comes to me in the first case as a eBay.Service.Core.Soap.AddressType type, and in the second as a com.paypal.soap.api.PayerInfoType type. Both have a lot of information in common (name, address, etc), but other than both having a base type of object, they don't have a lot in common. I'll read your article.
Sergey Alexandrovich Kryukov 2-Feb-13 19:38pm    
My point is: if you do have to "convert", your type hierarchy is not properly designed. In principle, you can possibly get a more specific advice, but only if you describe the goals of design, but in a way abstracted from your ideas of types and members used for implementation...
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900