Overlaying an existing object graph? - java

I have a database that contains an object graph. However, during use of the objects contained in the database I need to add additional functionality.
I cannot change the classes of the database, so I figure my only option is to make wrapper classes composed of their database equivalent objects and create forwarding methods along with methods and fields for the additional functionality. For instance:
public class Foo() {
private DBFoo databaseFoo;
// a bunch of forwarding methods to databaseFoo
// some methods for additional functionality
}
I'm struggling with a good pattern to construct my wrapper objects on top of the pre-existing database object graph. In particular how to reconstruct my graph of objects to mirror the graph in the database (with all its various references to other objects). Does anyone have experience with this sort of problem?

I can see two problems here:
a). Given some dbClassA, which references dbClassB, and collections of dbClassC, with dbClassB and dbClassC each themselves being arbitrarily complex: what design of proxy is appropriate? If dbClassA has methos
dbClassB getB() { ... }
we can quite easily see a mapping to
myClassB getB() { return new myClassB( theDbClassB.getB() ); }
or some such. But exactly what do we do with the collections?
List<dbClassC> getAllCs() { }
what does that become?
I figure that this is a solvable problem, just a matter of choosing some rules.
I suspect that you're more concerned about:
b). Creating all those proxy classes. Apply the chosen rule to many, many classes. One possible approach is to use code generator capabilities, for example JET in Eclipse. I've seen very good use of this capability for similar problems.

Related

Custom Constructor : Apache Cayenne 3.2M

I'm new to the API. It appears to me that you have to construct objects via the 'context' object like this:
ServerRuntime cayenneRuntime = new ServerRuntime("cayenne-project.xml");
context = cayenneRuntime.newContext()
...
MyEntity entity=context.newObject(MyEntity.class);
Rather than just creating Java Objects in the usual new() way:
MyEntity entity=new MyEntity();
But I want to create a constructor for my 'MyEntity' class that would do something like:
public MyEntity(String inputFile) {
...
do setters based on information derived from inputFile (size, time created etc).
...
How can I achieve this - ideally I want to keep the logic on the class MyEntity itself, rather than having a 'wrapper' class somewhere else to instantiate the object and perform the setting.... I guess I could have a 'helper' method which just the settings on a previously instantiated instance...but is there an idiom I'm missing here...?
You got it right about creating the object via 'context.newObject(..)' - this is the best way to do it and will keep you out of trouble. Still you can actually have your own constructor (provided you also maintain a default constructor for the framework to use):
public MyEntity(String inputFile) {
...
}
public MyEntity() {
}
Then you can create your object first, and add it to the context after that:
MyEntity e = new MyEntity(inputFile);
context.registerNewObject(e);
As far as idioms go, a very common one is to avoid business logic in persistent objects. ORM models are often reused in more than one application, and behavior you add to the entities doesn't uniformly apply everywhere. The other side of this argument is that anything but simplest methods depend on the knowledge of the surrounding environment - something you don't want your entities to be aware of.
Instead one would write a custom service layer that sits on top of the entities and contains all the business logic (often used with a dependency injection container). Services are not wrappers of entities (in fact services are often singletons). You can think of them as configurable strategy objects. In the Java world such layered design and this type of separation of concerns is very common and is probably the most flexible approach.
But if you want to hack something quickly, and don't envision it to grow into a complex multi-module system, then using a custom constructor or a static factory method in the entity is just fine of course.

Displaying various objects' instance variables in a JTable and modifying them

I am designing an application that has two widgets:
-A list that contains arbitrary objects
-A table that displays specific properties of the currently selected object
The goal is to be able to pick an object from the list, look at the properties, and modify them as necessary. The list can hold objects of various types.
So say the list contains Vehicle objects and Person objects
public class Person
{
public String name;
public Integer age;
}
public class Vehicle
{
public String make;
public String model;
}
If I click on a Person object, the table will display the name and age, and I can assign new values to them. Similarly, if I click on a Vehicle object, it will display the make and model in the table and allow me to modify them.
I have considered writing a method like
public String[] getFields()
{
return new String[] {"name", "age"};
}
Which returns a list of strings that represent the instance variables I want to look at, and use some reflection methods to get/set them. I can define this getFields method in all of the classes so that I can use the table to handle arbitrary objects that might be thrown into the list.
But is there a way to design this so that I don't resort to reflection? The current approach seems like bad design.
On the other hand, I could create multiple TableModel objects, one for every possible class. The table would know what rows to display and how to access the object's instance variables. But then everytime a new class is added I would have to define a new table model, which also sounds like a weak design.
You have a class (Vehicle) and you know the names of some properties (make, model) that you want to be able to manipulate dynamically for an instance of this class through a JTable UI.
You have various different approaches to chose from.
A. Use the reflection API
This is what the reflection API is made for. If you want something so dynamic, there is nothing wrong with using reflection. The performance overhead will not be significant for this use case.
B. Use a library like beanutils that is based on the reflection API
This should be easier than directly using the reflection API, but it has the drawback that you need to include another dependency in your project.
C. Create dynamically at runtime the different TableModel classes.
You can do this using either the java compiler API or javassist. Based on information available at runtime, you are able to compile a new class for each different type of table model. If you follow this approach you must be aware that the creation of the class is a heavy task, so the first time you create a TableModel the application will take some time to respond.
What to chose?
Of course this is your decision. For the specific use case, the overhead added by reflection or beanutils is insignificant, so probably it is better to chose between A or B. In another use case where performance is more critical, then you could examine the C approach, without forgetting the class creation response time problem.
EDIT:
I just realized that in this specific use case there is another important functionality required. Convert from String to the appropriate data type of each property and vice cersa. Beanutils has perfect support for that, so it gets a plus here.

Is a DAO Only Meant to Access Databases?

I have been brushing up on my design patterns and came across a thought that I could not find a good answer for anywhere. So maybe someone with more experience can help me out.
Is the DAO pattern only meant to be used to access data in a database?
Most the answers I found imply yes; in fact most that talk or write on the DAO pattern tend to automatically assume that you are working with some kind of database.
I disagree though. I could have a DAO like follows:
public interface CountryData {
public List<Country> getByCriteria(Criteria criteria);
}
public final class SQLCountryData implements CountryData {
public List<Country> getByCriteria(Criteria criteria) {
// Get From SQL Database.
}
}
public final class GraphCountryData implements CountryData {
public List<Country> getByCriteria(Criteria criteria) {
// Get From an Injected In-Memory Graph Data Structure.
}
}
Here I have a DAO interface and 2 implementations, one that works with an SQL database and one that works with say an in-memory graph data structure. Is this correct? Or is the graph implementation meant to be created in some other kind of layer?
And if it is correct, what is the best way to abstract implementation specific details that are required by each DAO implementation?
For example, take the Criteria Class I reference above. Suppose it is like this:
public final class Criteria {
private String countryName;
public String getCountryName() {
return this.countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
}
For the SQLCountryData, it needs to somehow map the countryName property to an SQL identifier so that it can generate the proper SQL. For the GraphCountryData, perhaps some sort of Predicate Object against the countryName property needs to be created to filter out vertices from the graph that fail.
What's the best way to abstract details like this without coupling client code working against the abstract CountryData with implementation specific details like this?
Any thoughts?
EDIT:
The example I included of the Criteria Class is simple enough, but consider if I want to allow the client to construct complex criterias, where they should not only specify the property to filter on, but also the equality operator, logical operators for compound criterias, and the value.
DAO's are part of the DAL (Data Access Layer) and you can have data backed by any kind of implementation (XML, RDBMS etc.). You just need to ensure that the project instance is injected/used at runtime. DI frameworks like Spring/Guice shine in this case. Also, your Criteria interface/implementation should be generic enough so that only business details are captured (i.e country name criteria) and the actual mapping is again handled by the implementation class.
For SQL, in your case, either you can hand generate SQL, generate it using a helper library like Spring or use a full fledged framework like MyBatis. In our project, Spring XML configuration files were used to decouple the client and the implementation; it might vary in your case.
EDIT: I see that you have raised a similar concern in the previous question. The answer still remains the same. You can add as much flexibility as you want in your interface; you just need to ensure that the implementation is smart enough to make sense of all the arguments it receives and maps them appropriately to the underlying source. In our case, we retrieved the value object from the business layer and converted it to a map in the SQL implementation layer which can be used by MyBatis. Again, this process was pretty much transparent and the only way for the service layer to communicate with DAO was via the interface defined value objects.
No, I don't believe it's tied to only databases. The acronym is for Data Access Object, not "Database Access Object" so it can be usable with any type of data source.
The whole point of it is to separate the application from the backing data store so that the store can be modified at will, provided it still follows the same rules.
That doesn't just mean turfing Oracle and putting in DB2. It could also mean switching to a totally non-DBMS-based solution.
ok this is a bit philosophical question, so I'll tell what I'm thinking about it.
DAO usually stands for Data Access Object. Here the source of data is not always Data Base, although in real world, implementations are usually come to this.
It can be XML, text file, some remote system, or, like you stated in-memory graph of objects.
From what I've seen in real-world project, yes, you right, you should provide different DAO implementations for accessing the data in different ways.
In this case one dao goes to DB, and another dao implementation goes to object graph.
The interface of DAO has to be designed very carefully. Your 'Criteria' has to be generic enough to encapsulate the way you're going to get the data from.
How to achieve this level of decoupling? The answer can vary depending on your system, by in general, I would say, the answer would be "as usual, by adding an another level of indirection" :)
You can also think about your criteria object as a data object where you supply only the data needed for the query. In this case you won't even need to support different Criteria.
Each particular implementation of DAO will take this data and treat it in its own different way: one will construct query for the graph, another will bind this to your SQL.
To minimize hassling with maintenance I would suggest you to use Dependency Management frameworks (like Spring, for example). Usually these frameworks are suited well to instantiate your DAO objects and play good together.
Good Luck!
No, DAO for databases only is a common misconception.
DAO is a "Data Access Object", not a "Database Access Object". Hence anywhere you need to CRUD data to/from ( e.g. file, memory, database, etc.. ), you can use DAO.
In Domain Driven Design there is a Repository pattern. While Repository as a word is far better than three random letters (DAO), the concept is the same.
The purpose of the DAO/Repository pattern is to abstract a backing data store, which can be anything that can hold a state.

NoSQL Schemaless data and statically typed language

One of the key benefits of NoSQL data stores like MongoDB is that they're schemaless. With dynamically typed languages this seem to be a natural fit. You can receive some arbitrary JSON inputs, perform business logic on the known fields, and persist the whole thing without first having to define the object.
What if your choice of language is limited to the statically typed, say Java? How could I achieve the same level of flexibility?
A typical data flow like the following:
JSON Input
Serialize to Java Object to perform business logic
Deserialize into BSON to persist in Mongo
where the serialization to object step is necessary since you want to perform business logic with POJOs, not JSON strings. However, before I can serialize the input into objects, I must define it first. What if the input contains additional fields undefined in the object? While they may not be used in the business logic, I may still want to be able to persist them. I have seem implementations where the undefined fields are put into a map, but am not sure if that's the best approach. For one, the undefined fields may be complex objects as well.
Schemaless data doesn't necessarily mean structureless data; the fields are typically known in advance and some type-safe pattern can be applied on top of it to avoid the Magic Container anti-pattern But this is not always the case. Sometimes keys are entered by the user and cannot be known in advance.
I've used the Role Object Pattern several times to give coherence to a dynamic structure. I think it is well suited here for both cases.
The Role Object Pattern defines a way to access different views of an object. The canonical example being a User that can assume several roles such as Customer, Vendor, and Seller. Each of these views has different operations it can perform and can be accessed from any of the other views. Common fields are typically available at the interface level (especially userId(), or in your case toJson()).
Here's an example of using the pattern:
public void displayPage(User user) {
display(user.getName());
if (user.hasView(Customer.class))
displayShoppingCart(user.getView(Customer.class);
if (user.hasView(Seller.class))
displayProducts(user.getView(Seller.class));
}
In the case of data with a known structure, you can have several views bringing different sets of keys into cohesive units. These different views can read the json data on construction.
In the case of data with a dynamic structure, an authoritative RawDataView can have the data in it's dynamic form (ie. a Magic Container like a HashMap<String, Object>). This can be used to query the dynamic data. At the same time, type-safe wrappers can be created lazily and can delegate to the RawDataView to assist in program readability/maintainability:
public class Customer implements User {
private final RawDataView data;
public CustomerView(UserView source) {
this.data = source.getView(RawDataView.class);
}
// All User views must specify this
#Override
public long id() {
return data.getId();
}
#Override
public <T extends UserView> T getView(Class<T> view) {
// construct or look up view
}
#Override
public Json toJson() {
return data.toJson();
}
//
// Specific to Customer
//
public List<Item> shoppingCart() {
List<Item> items = (List<Item>) data.getValue("items", List.class);
}
// etc....
}
I've had success with both of these approaches. Here are some extra pointers that I've discovered along the way:
Have a static structure structure to your data as much as possible. This makes things a lot easier to maintain. I had to break this rule and use the RawDataView approach when working on a legacy system. You may also have to break it with dynamically-entered user data as mentioned above. In which case, use a convention for non-dynamic field names such as a leading underscore (_userId)
Have equals() and hashcode() implemented such that user.getView(A.class).equals(user.getView(B.class)) is always true for the same user.
Have a UserCore class that does all the heavy lifting of common code such as creating views; performing common operations (like toJson()) returning common fields (like userId()); and implementing equals() and hashcode(). Have all views delegate to this core object
Have an AbstractUserView that delegates to the UserCore and implements equals() and hashcode()
Use a type-safe heterogeneous container (like ClassToInstanceMap) constructing/caching views.
Allow the existence of a view to be queried. This can be done with either a hasView() method or by having getView return Optional<T>
You can always have a class which provides both:
easy access to attributes you know about and optional fallback cases to older formats (for example it can return "name" if it exists, or older case of "name.first" + "name.last" if it doesn't (or some similar scenario))
easy access to unknown elements simulating the map interface
Whether you do a full validation or not, whether you allow extra undefined attributes or not depends on what you want to achieve. But I think that creating an abstraction which allows you either way of accessing the data is the best solution.
Hopefully over time, you'll get to the stage where your schema is pretty much stable and messing directly with the attributes is not needed anymore.
This is not well solved in Java due to the lack of dynamic types. One way this can be solved is using Maps.
Map
The object can again be a Map of objects.
This is not an elegant way but works in Java. An example : SnakeYaml library for YAML allows traversal in this way.

Removing copy/pasted code without an interface

I have two data access objects that are reverse generated and jar'ed up for use by my application. They represent tables that are very similar. One table has a few additional columns than the other. This is out of my control due to business oriented database ownership concerns.
The application currently has two implementations of a repository that operates on these DAOs. The implementations are very similar. One has a few extra operations that correspond to the extra columns on the second DAO. However with only a few exceptions, one implementation is a copy and paste of the other. The implementations are hundreds of lines long.
So I wanted to remove the copy/paste job. Ideally I could just stick an interface in front of the DAOs, and then maybe use an abstract class to hold the shared code (nearly all of it). However, I cannot put an interface in front of the DAOs. Remember they are reverse generated, and without upgrading our ORM software I don't think this is a reasonable choice (Kodo 3.x I believe, changing this is not in scope).
The only thing I can think of that would even work is some nastiness with reflection but that results in something much worse than I have now.
Any clever solutions?
edit: Here is very watered down code example
package one.dao
//reverse generated
class UserDao {
getFirstName(..);
setFirstName(..);
getLastName(..);
.... 50 more just like this
}
package two.dao
//reverse generated
class UserDao {
getFirstName(..);
setFirstName(..);
getLastName(..);
.... the same 50 more as above
getSomethingElse(..); //doesn't exist in one.dao.UserDao
setSomethingElse(..); //doesn't exist in one.dao.UserDao
}
class RepositoryOne(one.dao.UserDao userDao) {
//insert code here. perform operations on nearly all methods, lots of code
}
class RepositoryTwo(two.dao.UserDao userDao) {
//insert code here. same as Repository one
//some extra code that isn't above, maybe 10 lines
}
I am assuming you have some control over the duplicated code. If your code generator is producing all of it, you'll need to search for solutions within its API & configuration, I suspect.
When Inheritance doesn't work, try Composition. Make a third class to hold the shared code (SharedCode). Give each of the two existing classes a private member instance of the SharedCode class and make all routines implemented in SharedCode pass through methods to the member instance.

Categories