3

I have different types of objects representing the same business entity. UIObject, PowershellObject, DevCodeModelObject, WMIObject all are different representation to the same entity.

So say if the entity is Animal then I have AnimalUIObject, AnimalPSObject, AnimalModelObject, AnimalWMIObject, etc.

Now the implementations of AnimalUIObject, AnimalPSObject, AnimalModelObject are all in separate assemblies.

Now my scenario is I want to verify the contents of business entity Animal irrespective of the assembly it came from. So I created a GenericAnimal class to represent the Animal entity.

Now in GenericAnimal I added the following constructors:

GenericAnimal(AnimalUIObject)
GenericAnimal(AnimalPSObject)
GenericAnimal(AnimalModelObject)

Basically I made GenericAnimal depend on all the underlying assemblies so that while verifying I deal with this abstraction.

Now the other approach to do this is have GenericAnimal with an empty constructor an allow these underlying assemblies to have a Transform() method which would build the GenericAnimal.

Both approaches have some pros and cons:

The 1st approach:
Pros: All construction logic is in one place in one class GenericAnimal
Cons: GenericAnimal class must be touched every-time there is a new representation form.

The 2nd approach:
Pros: construction responsibility is delegated to the underlying assembly.
Cons: As construction logic is spread accross assemblies, tomorrow if I need to add a property X in GenericAnimal then I have to touch all the assemblies to change the Transform method.

Which approach looks better ?
or Which would you consider a lesser evil ?
Is there any alternative way better than the above two ?

Just to elaborate further based on the comments i received. I dont have the luxury the modify the structure of underlying objects, ie i cant change AnimalUIObject AnimalPSObject etc. The GenericAnimal is a construct introduced just for validation purposes by me.

Vishal Naidu
  • 341
  • 2
  • 6

3 Answers3

4

I think both approaches are pretty "evil".

I think what you really need is to start with the Animal class as your core class, and make the rest of the classes wrapper classes that use the Animal class to hold the representation. Validation is then performed against the Animal API.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    + I also feel the exposed design seems backwards. You beat me to put it in words. :) – madth3 Nov 17 '12 at 04:44
  • But I dont have the luxury to modify the underlying object structures. To elaborate We have multiple APIs from which we get these different type of objects. And We have wrapper assemblies for each of these entry points to get an Animal Entity. Now when i Get these objects before passing it to the validation layer i have to convert them to GenericAnimal. My question was basically should this conversion be in the GenericAnimal Class constructor or as a Transform method in each of the Wrapper assembly ? – Vishal Naidu Nov 17 '12 at 05:02
  • @VishalNaidu - I understand your question. The correct solution is to modify the underlying object structure. It is not a luxury ... it is a necessity (IMO). If you can't do that, then the two solutions you proposed are (IMO) equally bad. Both are going to result in duplicative code and more potential bugs. – Stephen C Nov 17 '12 at 05:19
  • The underlying code is production code. I cant touch that. The validation code which i would write will not be shipped. so the solution you proposed will be unacceptable. To add further, all these representations are from different clients like Powershell/UI they have their own entity representations, which i cannot break for validations. – Vishal Naidu Nov 17 '12 at 05:39
  • 1
    So if you have to write evil (test) code because the production code is badly designed, do it. But where I come from, it is a GOOD THING to fix badly designed production code. "I can't touch it" is a sign that something is dysfunctional in your organization's (or client organization's) development processes. – Stephen C Nov 18 '12 at 10:53
0

May be an opportunity for an abstract factory pattern ?

Yves_T
  • 1,170
  • 2
  • 10
  • 16
  • All these types cannot Extend / Contain GenericAnimal. GenericAnimal is a construct introduced later for validation purpose only, all the multiple implementations exist without GenericAnimal. – Vishal Naidu Nov 17 '12 at 05:04
0

I have different types of objects representing the same business entity. UIObject, PowershellObject, DevCodeModelObject, WMIObject all are different representation to the same entity.

Take a look to Design Patterns in general and in particular to Structural Pattern.

In my understanding the Decorator Pattern would be useful:

The decorator pattern can be used to extend (decorate) the functionality of a certain object at run-time, independently of other instances of the same class, provided some groundwork is done at design time. This is achieved by designing a new decorator class that wraps the original class

So it should be the first approach but w/o the cons:

The GenericAnimal class will have a constructor:

GenericAnimal(AnimalObject)

With AnimalObject either an interface or abstract class.

Cons: GenericAnimal class must be touched every-time there is a new representation form.

If you add another representation form make it implements or extends AnimalObject.

Tony Rad
  • 2,479
  • 20
  • 32