Design decision for object representation and conversion - oop

I need to map between different entities in order to create synch tool between two systems. The mapping is 1:1, and I have about 4-5 different entities that I will map between.
E.g
A1 -> B1
A2 -> B2
A3 -> B3
Communication is in JSON through REST API, and I will have to transform/convert an object into its JSON representation for different requests.
I wish to know about your ideas between the following decisions:
1) In each class, create a class method that knows how to convert to its corresponding object in the other system. Each class knows how to represent itself by implementing methods toJSON, toXML.
E.g
class A1 {
static A2 toA2(A1 a1) return { }
String toJSON() return { }
}
class A2 {
static A1 toA1(A2 a2) return { }
String to JSON() return { }
}
2) Straight away use a converter class (Object -> JSON) with methods for converting an object to the corresponding JSON in the other system. E.g.
Converter.entityAtoEntityBJSON(aEntityA) returns a JSON representation of entity A in entity B's system.
The second option will result in the converter class knowing about every entity, while in 1) only two classes know about each other. Also, should it be required to represent XML, each class can then implement a toXML().
What do you think?
Edit: added note about REST API.

Well although the first option seem compelling but i find that it breaks the SRP (Single Responsibility Principle) because it now has more than a single reason to change, each entity knows how to convert it self to other forms so whenever you change the representation format or structure you will have to modify each entity. So i prefer the second option to centralize change. i would use an interface like IMapper that takes an entity and converts it to an entity in the other system. This is similiar to the way most ORMs work to store you objects into databases.

Related

Recursively building a data class in Kotlin

I have am trying to create a recursive data class like so:
data class AttributeId (
val name: String,
val id: Int,
val children: List<AttributeId>?
)
The thing I'm struggling with now is building the data class by iterating over a source object.
How do I recursively build this object?? Is a data class the wrong solution here?
EDIT: Some more information about the Source object from which I want to construct my data class instance
The source object is a Java Stream that essentially* has the following shape:
public Category(final String value,
final Integer id,
final List<Category> children) {
this.value = value;
this.id = id;
this.children = children;
}
(For brevity the fields I don't care about have been removed from example)
I think I need to map over this stream and call a recursive function in order to construct the AttributeId data class, but my attempts seem to end in a stack overflow and a lot of confusion!
I don't think there's anything necessarily wrong with a data class that contains references to others.
There are certainly some gotchas.  For example:
If the list were mutable, or if its field was mutable (i.e. var rather than val), then you'd have to take care because its hashcode &c could change.
And if the chain of links could form a loop (i.e. you could follow the links and end up back at the original class), that could be very dangerous.  (E.g. calling a method such as toString() or hashCode() might either get stuck in an endless loop or crash the thread with a StackOverflowError.  You'd have to prevent that by overriding those methods to prevent them recursing.)  But that couldn't happen if the list and field were both immutable.
None of these issues are specific to data classes, though; a normal class could suffer the same issues (especially if you overrode methods like toString() or hashCode() without taking care).  So whether you make this a data class comes down to whether it feels like one: whether its primary purpose is to hold data, and/or whether the automatically-generated methods match how you want it to behave.
As Tenfour04 says, it depends what you're constructing these from.  If it naturally forms a tree structure, then this could be a good representation for it.
Obviously, you wouldn't be able to construct a parent before any of its children.  (In particular, the first instance you create would have to have either null or an empty list for its children.)  This would probably mean traversing the source in post-order.  The rest should fall out naturally from that.

Create ConvertTo method or create Convert class to handle convertions

I have type A which should be converted to type B.
Which is the best way to do it?
Create ConvertToB(I think it is better name than a.ToB()) method in A e.g.
A a = new A();
B b = a.ConvertToB();
Create special type which handles convert operations e.g.
Converter c = new Converter();
B b = Converter.AToB(a);
I think about second option because adding ConvertToB in type A breaks single responsibility principle.
On the other hand second option may end up in large Converter type with many methods.
Your question is more to do with Object Oriented Principles namely Information Hiding and Encapsulation. Generally breaking one results in chain of breaking other principles. See how
your option-1 of keeping conversion logic in A results in following code
class A {
private int a1;
public A(int a1) {
this.a1 = a1;
}
public B convertToB(){
int b1 = 0; // appropriate conversion from a1
return new B(b1);
}
}
observe here we DO NOT need public access to a1.
Your option-2 of keeping conversion logic in separate converter results in following code
class Converter {
public A bToA(B b){
int a1 = b.getB1();// Information hiding and encapsulation broken
// ---------
return new A(a1);
}
}
observe here we DO NEED public access to b1.
Obviously we encourage client code to use getX() methods and operate on somebody else's data and hence violation of encapsulation.
In my opinion if the conversion logic is not changing then Option-1 (convertToX()) should be used to protect Object Oriented nature. If we need to allow dynamic (run time) conversion logic then option-2 of separate Converter is better.
If A and B are two different presentations of same underlying data then see
Serialization: Converting from One Class to another class

OOAD - File-Format-Reader class vs Object-Model class: which should depend on which?

Let's consider, as an example, the domain of GPS and Geographical (GIS) entities.
We would model the meaningful geographic entities (points, paths, regions) as classes in any desired programming language, and these classes would be a conceptual, "implementation-free" representation of these entities.
On the other hand, there are a lot of file formats that save these features with more or less the same meaning. In the GPS domain the most common file formats are GPX, KML, ShapeFile, WellKnownText, etc.
Supposing, then, I want to create a GpsFeatureCollection class which would contain a Points property, a Paths property, and so on. Also, I would implement classes like GpsReader, KmlReader, ShapeFileReader (and their respective Writers) and so on.
THE QUESTION IS:
Which is the best practice in OOAD:
Have a GpsFeatureCollection to instantiate a FileFormat(Reader/Writer) class?
Have a GpsFeatureCollection to implement Read/WriteFromFormat methods instead of classes?
Have each file format reader to instantiate an empty GpsFeatureCollection, populate it with data read from file, then pass the populated object as a return value?
Have a mediator class to avoid any dependency between FileFormatClass and ObjectModelClass?
None of the above?
"Well, it depends..."
I am really interested in doing "the right thing". My immediate plans are to use Python, but most probably this would matter for other languages too. This is causing some "analysis paralysis" in my pet project currently...
Here is my take wherein I pass reader and writer instances to read() and write() methods, this seems to achieve good level of decoupling and yet provides flexibility to pick various readers and writers.
Code uses Java-like syntax
Declare a Reader interface, we will assuming multiple implementation such KMLReader,
ShapeFileReader, etc
interface Reader {
GpsFeatureCollection read();
}
Declare a Writer interface, we will assuming multiple implementation such KMLWriter, ShapeFileWriter, etc
interface Writer {
void write(GpsFeatureCollection c);
}
Let's declare GpsFeatureCollection class to have read and write methods which accept respective interfaces as parameter to perform the job.
class GpsFeatureCollection {
...
public static GpsFeatureCollection read(Reader r) {
return r.read();
}
public static void write(Writer w) {
w.write(this);
}
}
Some example of usage using different readers and writers.
// Reading data
GpsFeaureCollection data = GpsFeatureCollection.read(new ShapeFileReader("/tmp/shapefile"));
// Writing data
data.write(new KMLWriter("/tmp/kmlfile"));

Objects with two properties only

I am trying to decide on the best approach to the following problem:
I have a class called Desk. A desk has lots of properties. A Desk may have some objects on it. The current application specifies that it can have Pencils, Computers, or Cups on the desk. A few more objects may be added in the future. It can have one or none of each object. The Pencils have a property of Color, all of the objects have an ID and name. All of this information must be persistent so is stored in a database in some form.
Do I:
public class Desk {
public int property1;
public int property2;
...
public ISet<DeskObject> deskObjects;
}
public DeskObject {
public int deskObjectID;
public String name;
public DeskObject(name) {
this.name = name;
}
}
public Computer extends DeskObject {
DeskObject("Computer");
}
public Pencil extends DeskObject {
DeskObject("Pencil);
public Color color;
}
I also need to easily tell which objects a Desk contains in O(1) time. This means I will have to override hashcode and equals (probably by just returning the ID) for the DeskObjects so I can do set.contains(object). It seems like overkill and a misuse of objects. Surely there is a better solution?
If your domain is about desks and the objects they contain, then an object model like this is entirely warranted. The only question you need to ask yourself is this: Is this my domain model, or is it a computation model?
From the phrasing of your question, I would infer its rather the latter. Your objects do not contain any behavior (such as Desk.CleanNonRecentlyUsed()).
A domain model contains data and behavior (a true object model, I call this domain model), a computation model is data and separated behavior (procedural code).
If all your model needs to do is provide efficient lookups, you can chose any abstract representation that suits you. A lightweight object that captures just data is ok, but you could also use tuples (or to be .net specific since you mentioned GetHashCode: Annonymous classes) or just a Hashtable for the desk. Your computation model can be anything from an Index in your database (sounds reasonable in your example), a special object model, or dedicated algorithms over plain arrays.
Most of the time, it is not warranted to create a computation model when you already have a domain model. But sometimes it is.

Object Slicing, Is it advantage?

Object slicing is some thing that object looses some of its attributes or functions when a child class is assigned to base class.
Some thing like
Class A{
}
Class B extends A{
}
Class SomeClass{
A a = new A();
B b = new B();
// Some where if might happen like this */
a = b; (Object slicing happens)
}
Do we say Object slicing is any beneficial in any ways?
If yes, can any one please tell me how object slicing be a helpful in development and where it might be helpful?
In C++, you should think of an object slice as a conversion from the derived type to the base type[*]. A brand new object is created, which is "inspired by a true story".
Sometimes this is something that you would want to do, but the result is not in any sense the same object as the original. When object slicing goes wrong is when people aren't paying attention, and think it is the same object or a copy of it.
It's normally not beneficial. In fact it's normally done accidentally when someone passes by value when they meant to pass by reference.
It's quite hard to come up with an example of when slicing is definitively the right thing to do, because it's quite hard (especially in C++) to come up with an example where a non-abstract base class is definitively the right thing to do. This is an important design point, and not one to pass over lightly - if you find yourself slicing an object, either deliberately or accidentally, quite likely your object hierarchy is wrong to start with. Either the base class shouldn't be used as a base class, or else it should have at least one pure virtual function and hence not be sliceable or passable by value.
So, any example I gave where an object is converted to an object of its base class, would rightly provoke the objection, "hang on a minute, what are you doing inheriting from a concrete class in the first place?". If slicing is accidental then it's probably a bug, and if it's deliberate then it's probably "code smell".
But the answer might be "yes, OK, this shouldn't really be how things are structured, but given that they are structured that way, I need to convert from the derived class to the base class, and that by definition is a slice". In that spirit, here's an example:
struct Soldier {
string name;
string rank;
string serialNumber;
};
struct ActiveSoldier : Soldier {
string currentUnit;
ActiveSoldier *commandingOfficer; // the design errors multiply!
int yearsService;
};
template <typename InputIterator>
void takePrisoners(InputIterator first, InputIterator last) {
while (first != last) {
Soldier s(*first);
// do some stuff with name, rank and serialNumber
++first;
}
}
Now, the requirement of the takePrisoners function template is that its parameter be an iterator for a type convertible to Soldier. It doesn't have to be a derived class, and we don't directly access the members "name", etc, so takePrisoners has tried to offer the easiest possible interface to implement given the restrictions (a) should work with Soldier, and (b) should be possible to write other types that it also works with.
ActiveSoldier is one such other type. For reasons best known only to the author of that class, it has opted to publicly inherit from Soldier rather than providing an overloaded conversion operator. We can argue whether that's ever a good idea, but let's suppose we're stuck with it. Because it's a derived class, it is convertible to Soldier. That conversion is called a slice. Hence, if we call takePrisoners passing in the begin() and end() iterators for a vector of ActiveSoldiers, then we will slice them.
You could probably come up with similar examples for an OutputIterator, where the recipient only cares about the base class part of the objects being delivered, and so allows them to be sliced as they're written to the iterator.
The reason it's "code smell" is that we should consider (a) rewriting ActiveSoldier, and (b) changing Soldier so that it can be accessed using functions instead of member access, so that we can abstract that set of functions as an interface that other types can implement independently, so that takePrisoners doesn't have to convert to Soldier. Either of those would remove the need for a slice, and would have potential benefits for the ease with which our code can be extended in future.
[*] because it is one. The last two lines below are doing the same thing:
struct A {
int value;
A(int v) : value(v) {}
};
struct B : A {
int quantity;
B(int v, int q) : A(v), quantity(q) {}
};
int main() {
int i = 12; // an integer
B b(12, 3); // an instance of B
A a1 = b; // (1) convert B to A, also known as "slicing"
A a2 = i; // (2) convert int to A, not known as "slicing"
}
The only difference is that (1) calls A's copy constructor (that the compiler provides even though the code doesn't), whereas (2) calls A's int constructor.
As someone else said, Java doesn't do object slicing. If the code you provide were turned into Java, then no kind of object slicing would happen. Java variables are references, not objects, so the postcondition of a = b is just that the variable "a" refers to the same object as the variable "b" - changes via one reference can be seen via the other reference, and so on. They just refer to it by a different type, which is part of polymorphism. A typical analogy for this is that I might think of a person as "my brother"[**], and someone else might think of the same person as "my vicar". Same object, different interface.
You can get the Java-like effect in C++ using pointers or references:
B b(24,7);
A *a3 = &b; // No slicing - a3 is a pointer to the object b
A &a4 = b; // No slicing - a4 is a reference to (pseudonym for) the object b
[**] In point of fact, my brother is not a vicar.