Making unmodifiable objects - java

I have a Java application where the domain layer is decoupled from the UI by controllers. The problem is that these controllers can return domain objects, and can have domain objects as parameters.
Some of these returned domain objects are mutable, and this is what I want to prevent. I want it impossible for the UI (or future UI's) to directly modify the domain without accessing the controllers.
I tried two options:
In the first one I made sure that each class implemented an 'Unmodifiable' interface which contained only getters. And if I needed to return an object to the UI, I returned its 'Unmodifiable' interface. So that the UI could only view the getters.
The problem with this that they still can be cast easily to the original object and access is gained. At first I thought that this level of security was good enough, but it happend that someone accidentally casted some objects and used them in an incorrect way, and integrity was breached.
In the second one I tried to provide unmodifiable wrappers for each object that could be returned. But the problem is that these returned objects can be used as parameters for methods in the controllers and so they needed to be unwrapped in the controllers. I tried to make the uwrap() methode package-private, but then I have to put every specific wrapper class in the same package with the controllers and this is a bit inconvenient.
EDIT: 3th option:
(With thanks to vic) In the third option the object is wrapped by a unmodifiable wrapper, but can't be unwrapped by this wrapper. Each Unmodifiable is linked to its modifiable object in a Hashmap. So 'unwrapping' is done by getting the modifiable object that is linked to the unmodifiable object.
Does anyone know or has some ideas on how to make objects unmodifiable so they can be returned by a controller, and make it possible to make them modifiable again when they are passed back to the controllers?

What if the controllers store privately the mutable versions of the objects and return immutable versions of it to the "outer world". The mutable versions will have some kind of unique id, and the controllers will be able to unwrap it by looking up in a Collection of some sort.

Go for the State design pattern which is an excellent choice to represent an object's state.
Basically, whenever the UI wants to display a domain object, the controller gives it an immutable DTO object representing a snapshot of the object itself. This will restrict the UI layer to have only immutable snapshots of your domain objects. When the UI wants to make changes to your domain objects, it sends immutable state objects to the controller which use them to internally modify the corresponding domain objects.

Related

How to add java custom or string object to DAO model object at runtime?

I need to add new String object to Array of custom type object, ServiceOrderEntity in this case. I know that this kind of breaks ServiceOrderEntity integrity but I have to access this field from jsp. What is the best way to do it?
DAO class:
...
SQLQuery localSQLQuery = localSession.createSQLQuery(query).addEntity(ServiceOrderEntity.class);
localList = localSQLQuery.list();
Iterator itr = localList.iterator();
while (itr.hasNext()){
String field = "some value";
itr.next().append( field ); // something like that maybe....
}
return to Service class
...
Service class
...
List list = perform DAO request
model.addAttribute("serviceOrderList", localList);
....
UPDATE
I have all models generated by Hibernate and I don't want to touch them. I need to add to custom object, in this case ServiceOrderEntity or find workaround. I think I can make copy of it and append new field to it (using Dozer)? New fields is result of other complex subqueries.
List of ServiceOrderEntity objects at runtime:
-list
--[0]model.ServiceOrderEntity#d826d3c7
---createdBy = {....}
---serviceRequestFK{java.Lang.Integer} // << this one
--[1]
....
etc
I need to get name using serviceRequestFK in ServiceOrderEntity. As long as java doesn't allow hot fix (to add custom filed to already created object) I need to find a way to pass to JSP the name field as well. What is the right way?
I really don't want to include DAO mathod requests from jsp...
Create separate list of names?...
Since Java does not allow mix-ins (aka monkey-patching) you'll have to:
Add the field to the base entity.
Return a sub-class that includes this field.
If you'd like to add the field so that the Service class can do its job, then fair enough. However, if the new field is part of the payload in/out then consider instead for that particular service then consider:
Making use-case specific payloads for each service call.
Map the results of these onto your reusable object model. (You can use something like Dozer for this).
The rationale behind this suggestion is to follow the principles of contract-first development.
Your model will be more general purpose, and thus reusable. You can add reusable behaviors to your model classes. Your services will use these behaviors to orchestrate process. (As opposed to having 'anaemic' entitites).
Your service payloads can remain relatively stable over time. So changes to your model won't effect all of your service subscribers. (aka "don't spill your guts").

Class, Object, Entity: What's the difference?

I also see other terms as well: Entity Object, Value Object, etc. Are there other terms out there that I should know, and what do these terms refer to?
Can the differences between them, if any, be identified by reading code?
A class is a template for creating objects. Not all OO languages use classes (see Self, Javascript). Typically classes are implemented as objects.
An object is a bundle of data that is packaged with functions that act on that data (called methods). Calling a class's constructor allocates memory for the object and initializes its member variables.
An entity is an object that represents something that has an identity that the system is interested in tracking. Typical examples are Customers and Accounts.
A value object is a value, it doesn't have an identity, and two instances with the same value are considered to be identical. Typical examples are monetary amounts, locations, payment types.
A data transfer object is used for passing a bunch of data around. Typically they're used in distributed systems to send data as a bundle in order to avoid repeated network calls. Data transfer objects have no identity (or there is no expectation they should have any), they are just containers for data.
Generally you can tell the difference between entities and value objects because entities have a recognizable identity, and the system is concerned with creating them, storing them, and changing them. In cases where objects map to some database, entities have primary keys that are either some kind of composite natural key or an artificial key, while value objects are compared by value.
In general a class is a construct which defines a set of properties and methods/functions while an Object is the actual instance of a class which is created at runtime.
Sample class definition:
public class Example{
...
}
The following will create an instance of the Example class as an Object at runtime;
new Example();
Class defines an entity, while an object is the actualentity
Class is a conceptual modelthat defines allthecharacteristics and actions required of an object, whilean object is a real model
Class is a prototype of an object
All objects belonging to the same class have the samecharacteristics and actions

Is a Data Transfer Object the same as a Value Object?

Is a Data Transfer Object the same as a Value Object or are they different? If they are different then where should we use a DTO and where should we use a VO?
The programming language we are talking about is Java and the context is - there is a web application, which fetches data from a database and then processes it and ultimately the processed information is displayed on the front-end.
A value object is a simple object whose equality isn't based on identity.
A data transfer object is an object used to transfer data between software application subsystems, usually between business layers and UI. It is focused just on plain data, so it doesn't have any behaviour.
A Data Transfer Object is a kludge for moving a bunch of data from one layer or tier to another, the goal is to minimize the number of calls back and forth by packing a bunch of stuff into the same data structure and sending it together. Some people also use it, like Michael points out in his post here, so that the classes used by one layer are not exposed to the layer calling it. When I refer to DTO as a kludge, I mean there's not a precise abstract concept getting implemented, it's a practical workaround for helping with communication between application layers.
A Value Object is something where we're only interested in its value, like a monetary amount, a date range, or a code from a lookup table. It does not have an identity, meaning you would not be concerned, if you had several of them, of keeping track of which is which, because they are not things in themselves.
Contrast Value Objects to things that do have a unique identity in your system, which are called Entities. If you have a system where it tracks a customer making a payment, the customer and the payment are entities, because they represent specific things, but the monetary amount on the payment is just a value, it doesn't have an existence by itself, as far as your system is concerned. How something relates to your system determines if it is a Value Object or an Entity.
use a DTO at the boundary of your services if you don't want to send the actual domain object to the service's clients - this helps reduce dependencies between the client and service.
values objects are simply objects whose equality isn't based on identity e.g. java.lang.Integer
DTOs and value objects aren't really alternatives to each other.
They are different, but I've even used the two interchangeably in the past, which is wrong. I read that DTO (Data Transfer Object) was called a VO ( Value Object) in the first edition of the Core J2EE Patterns book, but wasn't able to find that reference.
A DTO, which I've sometimes called a Dumb Transfer Object to help me remember it's a container and shouldn't have any business logic is used to transport data between layers and tiers. It just should be an object with attributes that has getters/setters.
A VO however is similar to a JAVA Enum and represents a fixed set of data. A VO doesn't have object identity (the address of the object instance in memory), it is identified by its value and is immutable.
Martin Fowler, talking about Data Transfer Objects (DTOs):
Many people in the Sun community use the term "Value Object" for this pattern. I use it to mean something else.
So the term "Value Object" has been used to mean DTO, but as of him (and the other posters), its use as a DTO seems discouraged.
Good detailed answer in Matthias Noback article Is it a DTO or a Value Object?
In short a DTO:
Declares and enforces a schema for data: names and types
Offers no guarantees about correctness of values
A value object:
Wraps one or more values or value objects
Provides evidence of the correctness of these values
Maybe because of lack of experience, but I would put it this way: It's the matter of scope.
DTO has word transfer in it so it means some parts of the system will communicate using it.
Value object has smaller scope, you will pass set of data in value object instead in array from one service to the other.
As much as I understood niether of them is "object whose equality isn't based on identity".

Using annotation for an object sorter?

I am working a container to hold a list of objects (of the same class) the have certain fields that use a custom RetentionSortable annotation. The purpose of the annotation is two fold:
To mark the field as able to be compared to another objects same field.
And to give the sort name of the field (eg. Modification Date or First Name).
The container will then walk through the list of objects (remember they are like) and gather the list of RententionSortable's that the object contains and pass the list to the GUI. The GUI will display the list and request a sortable selection and return it to the sortable which will then sort the list based on the RetentionSortable selected.
The purpose of this method or sorting object is to allow me to create a small container that can generically accept any object and sort it as long as it has at least one RetentionSortable field.
My gut screams that this is bad practice and that relying this much on reflection is a bad idea but my tests work flawlessly and better than I expected.
Is using annotation reflection to find all the fields that are annotated by a particular annotation good practice for abstract object sorting?
Annotations are there for convenience, and your use is making the situation more convenient, so it seems reasonable. The alternative is to maintain a separate dictionary of which fields are sortable for which objects, and is slightly more cumbersome but slightly better from a seperation of concerns point of view.
The question is really whether your object should know about the annotations or not (is the object going to be reused in another situation where the annotations do not make sense or conflict). With a separate list of sortable fields, you can pick which to apply in any given case.
If the convenience trade-off works for you, then you should stick with the annotations, just so long as you are aware of the potential design ramifications (which may be nothing for your particular case).
How do you think basically every annotation-driven configuration framework works? "Give me all the of such-and-such type fields annotated with '#Inject'" or "give me everything in package baz.plugh annotated with '#Controller'".
Whether or not it's good for "abstract sorting" or not, I don't see why not. If it works, and eliminates the need for things like bean mappers and bean info classes, what's the issue?

When working with objects that are saved to a database that have a relationship, do you load the whole objects or just the id?

Suppose I have a CatHerder and he has Cats, when I getCatHerderByID(String id) should I load in the CatHerder and set an arrayList of cats or an arrayList of catIDs?
getCatHerderByID() should be a method which returns an object of type CatHerder, which can have a property catsOwned which will contain a list of IDs, populated by the constructor. In addition, you can have a method on the CatHerder object called getCats() which returns an array of Cat consisting of the IDs in the CatHerder object. You shouldn't load unnecessary information just because it has a relationship with the information you actually want -- in many cases, everything will have a relationship with the data you actually want.
When you don't have much data or many concurrent users, you can go with either way.
One easy options would be to add an additional parameter specifying whether to return a "deep copy" including the relations, or just the attributes of the object itself.
Stay away from the urge to add more parameters, or you will end up re-implementing SQL :)

Categories