Use structures to group individual attributes or not? - oop

I'm in doubt of how to get the best of ABAP structures and class attributes.
Let's say that I have the object Operation with 4 fields: operation id, type, description and date.
Now I can create a class with this 4 attributes, but then if I want to have a constructor, I need either 4 individual parameters or a structure than needs to be mapped to each attribute. The same happens if I want to get all this object data in one structure, for instance to return via RFC. Then a method get_operation_details( ) will need to map all of them one by one.
If I use a structure type ty_operation_details as a single class attribute, then when I add a field to the structure would also keep the constructor valid and the get_operation_details( ) method would also be always OK. However it seems wrong to have something like Operation->get_details( )-operationID, instead of operation->operation_ID if I had the attribute directly in the public section with READ-ONLY. I guess the first approach is more correct in the OO world, but we lose some of the ABAP benefits.
What do you recommend to use? Maybe one thing it could allow the first option and use structures at the same time would be a CORRESPONDING statement able to map class attributes to a flat structure, but I don't think this is possible.

Like most things, your design should follow your usage. If you primarily use a set of attributes together, consider grouping them in a structure. If you primarily use them individually, or in varying recombinations, keep them separate.
Some considerations:
Grouping makes calls shorter if you always create/update/delete a set of attributes together. You already identified this advantage.
Grouping reveals logical relations between fields, that are not clear when keeping the fields separate. For example, this could reveal that one part of your parameters is mandatory, while the rest forms several optional sets.
Grouping simplifies features that operate on state, such as the Memento or the Flyweight pattern, in that it allows to extract, store, and restore the object's state as a single structure.
Also, like many other things, there may be benefit in turning this either-or question into a I'll simply use both. For example, if your class has four individual properties, why not still offer a method that sets or gets them as a structure; of course, this will add some mapping, but the mapping would remain encapsulated within your own class, while consumer get an easy-to-consume interface.

Related

Class with a list of materials: best practice

I've created the custom class ZMaterial that can be instantiated passing an ID to the constructor which sets the properties for a single material using SELECTs and BAPIs. This class is basically used to READ and UPDATE a single material.
Now I need to create a service to return a list of materials. I already have the procedural code for it in a static method (for now actually a function module), but I would like to keep using a full OOP approach and instantiate a list of my custom material object. The first approach I found is to enhance the static method to instantiate a list of my single material object after the selects are executed and I have the data in internal tables, but it does not seem the most OOP.
The second option in my mind is to create a new class ZMaterialList with one property being a list of objects ZMaterial and then a constructor with the necessary input parameters for the database select. The problem I see with this option is that I create a full class just for the constructor.
What do you think is the best way to proceed?
Create a separate class to produce the list of materials. The single responsibility principle says each class should do exactly one thing. In all but the most simple cases, using a thing is a different responsibility than producing it.
Don’t make a ZMaterialList class. A list’s focus would be managing the list items, i.e. adding, removing, iterating, sorting etc. But you should be fine with a regular STANDARD TABLE OF REF TO ZMaterial.
Make a ZMaterialReader, -Repository, -Query or -Factory class or the like, depending on the precise way you want to produce the ZMaterials. Readers read by keys, repositories read and write, queries use varying sets of selection criteria, factories instantiate with possibly different sets of inputs.
You can well let that class use the original FUNCTION underneath. It’s good style to exploit what’s already there. Just make sure you trust that code, put it in a test harness, and keep it afar from the rest of your oo code.
Extract all public interaction of ZMaterial to an interface and use only that interface. That allows you to offer alternative implementations of ZMaterial, ones that differ in the way they are produced or how they store their data.
Split single production from mass production. Reading MARA to retrieve a single material is okay. But you don’t want thousands of ZMaterials reading MARA individually - that wrecks performance.
Now you’ve got the interface, you could offer a second implementation of ZMaterial whose constructor receives all relevant data and relies on it already having been validated to avoid additional SELECTs.
You could also offer an implementation that doesn’t store its data at all but only stores pointers to rows in internal tables somewhere else. See the flyweight pattern for ideas.
If you expect mass updates on the materials, such as “reclassify all of these as B”, consider extracting these list-oriented operations to separate classes as well.

When do I keep a map<Identifier, Object> vs a Collection<Object with identifier as field>

There is one question that I often ask myself while designing a program, and I am never quite sure how to answer it.
Let's say I have an object with multiple fields, amongst which there is one serving as the identifier to that specific object. Let's also say that I need to keep track of a List of such objects somewhere else.
I now have three, and probably even more, options on how to go about it:
Have my object contain its own identifier, and all its other fields. I now use a simple array (or whatever simple list collection) of my objects where I need it. When I am looking for one specific object, I loop through my list and check for identifier equality.
Pros: 1. "Clarity" for each object instance. 2.?
Cons: Manipulating a collection of these objects gets annoying
Have my object contain all fields beside its identifier. I now use a Map with identifier as key, and object as value. When looking for one specific object, I just lookup the identifier in the map.
Pros: easy lookups and insertions,?
Cons: object instance itself doesnt know what it is,?
Combination of both: use a map with identifier as key and object having its own identifier as a field as value.
Pros: mentioned above.
Cons: looks redundant to me.
What situations would call for what? Let's use the standard hello-world example of networking for example, a chat server: how would I handle multiple "groups/channels" people are in?
What about other applications?
Your question is very wide and, actually, contains two questions.
First is “Which data structure is better — dictionary or list?”. The answer is: it depends on performance you want to achieve on insertion and search operations. Basically if you need to look through the collection, then list is ok, and if you need to have fast look-up, then dictionary is better. Dictionary has more memory overhead than list.
The second is “Do I need to have an Id field inside an entity or can I use built in hash code?”. The answer is: it depends on how you will use your object. If you want Id just to store it in a dictionary, then, most likely, you can go with hash code. There is nothing wrong with storing Id of an entity inside that entity. Either you use Id or hash code, you need to be sure that this entity will be uniquely identified by id or hash. That's the main concern with it.
You can override GetHashCode method and make it return Id of your entity. Sometimes you can find such implementation when hash code is required for collection and Id is required for database.
So, it really doesn't matter what you will choose in the end if both approaches are working for you right now.
A map<Identifier, Object> will offer you O(1) performance when retrieving an object based on its identifier. There certainly are situations where you want to achieve that.
However, in other cases it might be redundant to use this approach. It all depends on the situation at hand.
Two guidelines may answer this question:
A use case that calls for a lookup where there is an expectation of a 1:1 relationship between the key and value implies a Map structure.
OOP implies that a key which is so closely related to an object as to preform a lookup should be encapsulated within that object.
Regarding the question of redundancy, consider the key in a map is nothing but an index. Indexes are as common in data as in books.

OO Programming: Summary of objects

I want to have two classes that are independent of each other. A content type and a URL. A URL will have a conent type.
Could I add into the content type a summary field, which could be easily queried (e.g content type X has 10 URL's) or would I need to query all of the URL's and pull out the content type that way?
A URL can also be associated with other classes (not just this content type), which is why I don't create a superclass of content type, and then a sub URL class.
That depends. Basically what you are asking is the following: Given a 1:n relationship, how can I automatically query both directions?
If you use a database to store your data, most object-relational mappers give you this functionality for free. If you don't, you need to handle it yourself.
There are various options. The most simplistic approach is to iterate all URLs and filter the ones that match the queried content type. This is most likely the responsibility of some container. This variant is very easy to implement but takes O(number of URLs) time to execute the query. So if you just have a few URLs, this may be the way to go.
The other option is to explicitly store the inverse relationship. Either directly in the content types or in a container (e.g. within a hash map). The main problem of this approach is keeping both pairs of a relationship in sync. You could use the setter of the URL's content type property to update the content type's URLs property. The task of synchronizing the relationships could also be handed over to a container. Anyway, this option is significantly faster but requires some programming effort. Depending on your concrete scenario, this might be more or less work.

How to bind an NSTableView to multiple core data entity types

I'm writing an application to help diabetics manage their condition. Information that is tracked includes blood sugar results, nutrition, exercise, and medication information.
In similar applications these entries are all presented in a single table view even though each type of entry has different fields. This data is manually tracked by many diabetics in a logbook, and I'm looking to keep that paradigm.
Each entry has some common information (timestamp, category, and notes) as well as information specific to each entry type. For instance, meal entries would have detailed nutrition information (carb counts, fiber, fat, etc), medication entries would indicate which medication and dosage, etc.
I've considered two different approaches but I'm getting stuck at both a conceptual level and a technical level when attempting to implement either. The first approach was to create an abstract entity to contain all the common fields and then create entities for each log entry type (meals, meds, bg, etc.) that are parented to the abstract entity. I had this all modeled out but couldn't quite figure out how to bind these items to an array controller to have them show up in a single table view.
The second approach is to have one entity that contains the common fields, and then model the specific entry types as separate entities that have a relationship back to the common record (sort of like a decorator pattern). This was somewhat easier to build the UI for (at least for the common field entity), but I come to the same problem when wanting to bind the specific data entities.
Of course the easiest approach is to just throw all the fields from each different entry type into one entity but that goes against all my sensibilities. And it seems I would still run into a similar problem when I go to bind things to the table view.
My end goal is to provide an interface to the user that shows each entry in chronological order in a unified interface instead of having to keep a separate list of each entry type. I'm fine with adding code where needed, but I'd like to use the bindings as much as possible.
Thanks in advance for any advice.
Don't get bogged down with entity inheritance. You shouldn't use it save duplicate attributes like you would with classes. It's major use is allow different entities to be in the same relationship. Also, entity inheritance and class inheritance don't have to overlap. You can have a class inheritance hierarchy without an entity inheritance hierarchy.
I'm not sure I understand exactly what you really need but here's some generic advice: You shouldn't create your data model based on the needs of the UI. The data model is really a simulation of the real-world objects, events or conditions that your app deals with. You should create your data model first and foremost to accurately simulate the data. Ideally, you should create a data model that could be used with any UI e.g. command-line, GUI, web page etc.
Once your model is accurately setup, then whipping up the UI is usually easy.

How to model a relationship that NHibernate (or Hibernate) doesn’t easily support

I have a situation in which the ideal relationship, I believe, would involve Value Object Inheritance. This is unfortunately not supported in NHibernate so any solution I come up with will be less than perfect.
Let’s say that:
“Item” entities have a “Location” that can be in one of multiple different formats.
These formats are completely different with no overlapping fields.
We will deal with each Location in the format that is provided in the data with no attempt to convert from one format to another.
Each Item has exactly one Location.
“SpecialItem” is a subtype of Item, however, that is unique in that it has exactly two Locations.
“Group” entities aggregate Items.
“LocationGroup” is as subtype of Group.
LocationGroup also has a single Location that can be in any of the formats as described above.
Although I’m interested in Items by Group, I’m also interested in being able to find all items with the same Location, regardless of which group they are in.
I apologize for the number of stipulations listed above, but I’m afraid that simplifying it any further wouldn’t really reflect the difficulties of the situation. Here is how the above could be diagrammed:
Mapping Dilemma Diagram http://www.freeimagehosting.net/uploads/592ad48b1a.jpg
Analyzing the above, I make the following observations:
I treat Locations polymorphically, referring to the supertype rather than the subtype.
Logically, Locations should be “Value Objects” rather than entities since it is meaningless to differentiate between two Location objects that have all the same values. Thus equality between Locations should be based on field comparisons, not identifiers. Also, value objects should be immutable and shared references should not be allowed.
Using NHibernate (or Hibernate) one would typically map value objects using the “component” keyword which would cause the fields of the class to be mapped directly into the database table that represents the containing class. Put another way, there would not be a separate “Locations” table in the database (and Locations would therefore have no identifiers).
NHibernate (or Hibernate) do not currently support inheritance for value objects.
My choices as I see them are:
Ignore the fact that Locations should be value objects and map them as entities. This would take care of the inheritance mapping issues since NHibernate supports entity inheritance. The downside is that I then have to deal with aliasing issues. (Meaning that if multiple objects share a reference to the same Location, then changing values for one object’s Location would cause the location to change for other objects that share the reference to the same Location record.) I want to avoid this if possible. Another downside is that entities are typically compared by their IDs. This would mean that two Location objects would be considered not equal even if the values of all their fields are the same. This would be invalid and unacceptable from the business perspective.
Flatten Locations into a single class so that there are no longer inheritance relationships for Locations. This would allow Locations to be treated as value objects which could easily be handled by using “component” mapping in NHibernate. The downside in this case would be that the domain model becomes weaker, more fragile and less maintainable.
Do some “creative” mapping in the hbm files in order to force Location fields to be mapped into the containing entities’ tables without using the “component” keyword. This approach is described by Colin Jack here. My situation is more complicated than the one he describes due to the fact that SpecialItem has a second Location and the fact that a different entity, LocatedGroup, also has Locations. I could probably get it to work, but the mappings would be non-intuitive and therefore hard to understand and maintain by other developers in the future. Also, I suspect that these tricky mappings would likely not be possible using Fluent NHibernate so I would use the advantages of using that tool, at least in that situation.
Surely others out there have run into similar situations. I’m hoping someone who has “been there, done that” can share some wisdom. :-)
So here’s the question… Which approach should be preferred in this situation? Why? Is there a better option that I haven't considered?
Just a few observations / questions...
if the different location formats have no overlapping fields, what is the commonality in them which would make them candidates for a subclass hierarchy? Can you actually define a common interface for the base class Location?
is a TypeALocation comparable with a TypeBLocation?
are the two locations in SpecialItem of the same type, or can they be mixed?
can an item change its location to a different type runtime?
As you state above, value objects can't be polymorphic. Based on what you describe, I don't see how can you treat locations polymorphically.
Update If you can't define a common base interface for your location types, it is very awkward to try and treat them polymorphically, regardless of whether there is ORM or not. Taking your example below, even for accessing any information about the actual location I live, you needed to downcast it to either a street address or a lat/long coordinate. Polimorphism is meant exactly to avoid the need for such downcasts (and switches on type fields, etc.)!
Looking at the options you describe above, with all this taken into account:
Just as you, I don't like it either (hardly suprising).
Can be a viable option if there aren't many location types and you can be reasonably sure that you have implemented all the types ever needed. In this case the domain class would practically be the analog of a C union, with a type field. It is a bit awkward to use, but the polymorphic attempt would be even more awkward IMHO.
It is definitely an interesting idea which I will probably experiment with in a pet project sometime, but I am not quite sure I would like such tricks in my production code. I guess it could also be done with a custom mapping type which would map your component to a specific subclass. But then again, we're back trying to fit these incompatible types into a type hierarchy... the only good reason to try this path is if there are many location types and/or new types may appear in the future.