I have a domain object Invoice that has around 60 attributes, some are mandatory and some are optional. This Invoice class is a representation of a record in the underlying DB table with certain columns values wrapped with application layer classes (like Enum for a simple integer stored in the DB, Currency for a double etc.,).
This Invoice class is currently defined as follows:
Public full-arg constructor.
Public getters.
Protected setters.
Now, it is scaring the clients of this class who create an Invoice object, to pass all 60 odd attributes to the constructor. I am adamant against making the setters public for obvious reasons.
Could you please suggest a better way to allow creation/modification of this invoice object? Please let me know if you need more details.
Using the Builder Pattern
Use the Builder Pattern that Joshua Bloch describes in his book Effective Java 2nd Edition. You can find the same example in http://www.javaspecialists.eu/archive/Issue163.html
Pay special attention to the line:
NutritionFacts locoCola = new NutritionFacts.Builder(240, 8) // Mandatory
.sodium(30) // Optional
.carbohydrate(28) // Optional
.build();
Using BeansUtils.populate
Other way is to use the method org.apache.commons.beanutils.BeanUtils.populate(Object, Map) from Apache Commons BeansUtils. In this case, you need a map to store the object's properties.
Code:
public static void main(String[] args) throws Exception {
Map<String, Object> map = new HashMap<>();
map.put("servingSize", 10);
map.put("servings", 2);
map.put("calories", 1000);
map.put("fat", 1);
// Create the object
NutritionFacts bean = new NutritionFacts();
// Populate with the map properties
BeanUtils.populate(bean, map);
System.out.println(ToStringBuilder.reflectionToString(bean,
ToStringStyle.MULTI_LINE_STYLE));
}
Output:
NutritionFacts#188d2ae[
servingSize=10
servings=2
calories=1000
fat=1
sodium=<null>
carbohydrate=<null>
]
What you could do maybe would be to decompose your object into smaller ones. As per the comments above, you might require the users to build these new objects however, depending on your database design, you might just need to pass a primary or foreign key to the class.
The class will then have some behaviour which will seek the relevant data from the database. This obviously could increase the load on your database server, but it will allow you to less complex (albeit, more in amount) classes. The reduction in complexity will most likely increase the chances of code re-usability as well as make it more maintenance friendly.
As suggeste #Jake King , it is always better to 60 attributes to composite into smaller data objects.
While doing this, I will look into one aspect, which possible combinations are optional and I will compose in that way. For example, Mailing Address is optional if Client Clicks on to say that use the Current Address and Mailing Address.
Build Constructors around these composed objects will help you manage/maintain the Class easily and effeciently.
If your Invoice Object has 60 attributes and you are sure that you wont be requiring some of them there is no need create getter and setter for those attribute.it is always recommended to create getter setter of the attributes which you required in code. but you need to make sure that the omitted field should allow null contraint in database.
else if you required all the 60 attributes in the code then create different contructor as per required by the client.if client needs to pass only 4 then create contructor accepting 4 parameters and you can set default values for attributes in the database whose values are not passed by the clients.
Related
Trying to create my own shiny ORM system (not that important information), I'm currently struggling with java inheritance limits. Here is the concept:
public class UserDescriptor implements TableDescriptor {
public static final UserDescriptor INSTANCE = new UserDescriptor();
private UserDescriptor() {
}
public String getTableName() {
return "user";
}
// ======= Columns definition
public static final AbstractColumn<Integer> ID =
new IntegerColumn("id", AbstractColumn.Attribute.NOT_NULL);
public static final AbstractColumn<String> ALIAS =
new StringColumn("alias");
// ... and some more...
}
Hope it's clear enough. These are then used with static import like:
map = JDBCHelper.selectFirst(UserDescriptor.INSTANCE, Arrays.asList(ID, ALIAS));
where the list (2. param) is what I need to fetch from table defined by UserDescriptor. map variable holds custom map, which internally has signature similar to <AbstractColumn<T>, T> and method
public T getValue(AbstractColumn<T> col);
so I'm getting the value then type-safe
Integer id = map.getValue(ID);
String alias = map.getValue(ALIAS);
This concept is currently working, but:
TableDescriptor concept is a bit verbose. I have many tables and need many times to write twice the type and this long start of each column definition
public static final AbstractColumn<Integer>
This line is result of well-know java limitation - not possible to extend enum class. Otherwise the TableDescriptor would be abstract class with field AbstractColumn<T> defined by explicit constructor and every successor would be enum with columns defined within instances.
This would come with following advantages:
Possibility to make whole thing (conditions, returning columns definition, .....) more type-safe, eg. only enum of specific type can be listed in List parameter for select from single table,
better readability and basis for new developers,
getAllColumns functionality can be done without reflection.
This is unfortunately not possible, so you're now my last hope. I know enum inheritance stuff is on SO many times, but I already have already working solution and maybe it's possible to improve it some other way in this specific case..
What may be some kind of hint - these descriptors must now be int the API part of project to selects to be possible. I was struggling with the way I'd put it to impl. and in API I'll let only some enum listing only overview of the columns:
public enum UserTableColumns {
ID,
ALIAS
}
and map it somehow to UserDescriptor - then I'd be able to use in most cases only this enum, but I didn't figure out yet how this should work..
Current signature of selectFisrt method is following:
CustomResultMap selectFirst(TableDescriptor td, List<AbstractColumn<?>> cols);
and one possible modification would be to change List<AbstractColumn<?>> to some list of enum values, which will be mapped to TableDescriptor so I can check that the values are from single table.
Edit: clarification
I'll try to summarize what I understood from your question and the comments:
Your API should contain an enum like UserTableColumn as well as a method that currently looks like T get(AbstractColumn<T>) but should return the correct type based on the generic type of the column. Since AbstractColumn basically is meant to be an implementation detail you'd like to replace that with the enum, e.g. to get something like this (which won't compile): T get(UserTableColumn<T>).
(Please correct me if I made a mistake somewhere.)
The problem with that is that generics are a compile time tool, i.e. the compiler needs to know about the type that is being used. However, enum values can't have generic types and any parameter (e.g. ID(Integer.class)) would not be available at compile time since it's basically an instance (i.e. runtime) value.
Thus you'll need something like AbstractColumn<T> although that might be another class that only contains the generic type (and implements some interface). That probably requires some manual definition or the use of a preprocessor (have a look at how Hibernate does it for its criteria api).
My context: User will add one of numerous type of company into himself in the form. For that form, I created enum to fill the listbox instead of pulling the database.
I will try my best to explain what my question is: In my context, whats the difference between using enum and domain for showing and save into database? Performance, logic, bestpractice?
Because when user saves a companyType, it will save an int into database, but I can see what description it is. using a method #Overide toString().
Instead of using enum as code below, I could have created a domain with id and description moreover adding two registers into my db pulling into to form.
class Company{
CompanyType companyType
}
Use this as enum
enum CompanyType {
MARKET('Market', 1),
SHOP('Shop', 2)
// ... etc of code
}
or use this as domain
class CompanyType {
Long id
String description
}
sorry for my bad english.
The main factor you should consider is how much the Company type data may change, if you are able to list all the possible company types you will be using and are sure that no frequent update are expected, then the enum is the reasonable choice, no table or POJO needed, in the other hand, if it's meant to change, adding, updating and removing company type, then the table and the POJO class are the right choice.
two points:
performance: enum values are saved as a String (usually as enum.toString()) in a db, and don't require any FK-relations and have less overhead during ORM transformations
flexibility: enum values can be updated only with new deployment. If you need to change the value of the existing enum constant, you would have to migrate your data
I would use enums instead of a domain class, as the performance is usually more important
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.
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.
Background:
I found this article on JavaWorld, where Allen Holub explains an alternative to Getters/Setters that maintains the principle that the implementation of an object should be hidden (his example code can also be found below).
It is explained that the classes Name/EmployeeId/Money should have a constructor taking a single string - the reasoning is that if you type it as an int, and later need to change it to a long, you will have to modify all the uses of the class, and with this pattern you don't have to.
Question 1:
I was wondering: doesn't this simply move the problem to the parsing of the String parameters being tossed about? For example, if all the code using the EmployeeId (received from the Exporter) parses the String into an int, and suddenly you start exporting long values, you need to modify exactly as many uses... and if you start out parsing it as a long it might well have to change to a double (even though that makes no sense for id's)... and if you can't be sure what to parse the String into, you can't implement anything.
Question 2:
Besides this question, I have another: I realise that the article is over seven years old, so could anyone point me to some recent overviews concerning OO-design, and specifically to ideas concerning the getter/setter and implementation hiding debate?
Listing 1. Employee: The Builder Context
public class Employee
{ private Name name;
private EmployeeId id;
private Money salary;
public interface Exporter
{ void addName ( String name );
void addID ( String id );
void addSalary ( String salary );
}
public interface Importer
{ String provideName();
String provideID();
String provideSalary();
void open();
void close();
}
public Employee( Importer builder )
{ builder.open();
this.name = new Name ( builder.provideName() );
this.id = new EmployeeId( builder.provideID() );
this.salary = new Money ( builder.provideSalary(),
new Locale("en", "US") );
builder.close();
}
public void export( Exporter builder )
{ builder.addName ( name.toString() );
builder.addID ( id.toString() );
builder.addSalary( salary.toString() );
}
//...
}
Question 1:
String parsing seems strange. IMHO you can only do so much to anticipate future enhancements. Either you use a long parameter right from the start to be sure, or consider adding additional constructors later. Alternatively you can introduce an extensible parameter class. See below.
Question 2:
There are several scenarios in which the builder pattern can be useful.
Complex Object creation
When you are dealing with very complex object that have lots of properties
that you would preferably only set once at object creation, doing this with
regular constructors can become hard to read, because the constructor will
have a long list of parameters. Publishing this as an API is not good style
because everyone will have to read the documentation carefully and make sure
they do not confuse parameters.
Instead when you offer a builder, only you have to cope with the (private)
constructor taking all the arguments, but the consumers of your class can
use much more readable individual methods.
Setters are not the same thing, because they would allow you to change object
properties after its creation.
Extensible API
When you only publish a multi-parameter constructor for your class and later
decide you need to add a new (optional) property (say in a later version of your software)
you have to create a second constructor that is identical to the first one, but
takes one more parameter. Otherwise - if you were to just add it to the existing
constructor - you would break compatibility with existing code.
With a builder, you simply add a new method for the new property, with all existing
code still being compatible.
Immutability
Software development is strongly trending towards parallel execution of
multiple threads. In such scenarios it is best to use objects that cannot
be modified after they have been created (immutable objects), because these
cannot cause problems with concurrent updates from multiple threads. This is
why setters are not an option.
Now, if you want to avoid the problems of the multi-parameter public constructors,
that leaves builders as a very convenient alternative.
Readability ("Fluent API")
Builder based APIs can be very easy to read, if the methods of the builder are
named cleverly, you can come out with code that reads almost like English sentences.
In general, builders are a useful pattern, and depending on the language you are using, they are either really easy to use (e. g. Groovy) or a little more tedious (e. g. in Java) for the provider of an API. For the consumers, however, they can be just as easy.
There are many problems with constructors that take arguments (for example, you can't build the object in several steps). Also if you need lots of arguments, you will eventually get confused about parameter order.
The latest idea is to use a "fluent interface". It works with setters that return this. Often, set is omitted from the method name. Now you can write:
User user = new User()
.firstName( "John" )
.familyName( "Doe" )
.address( address1 )
.address( address2 )
;
This has several advantages:
It's very readable.
You can change the order of parameters without breaking anything
It can handle single-value and multi-value arguments (address).
The major drawback is that you don't know anymore when the instance is "ready" to be used.
The solution is to have many unit tests or specifically add an "init()" or "done()" method which does all the checks and sets a flag "this instance is properly initialized".
Another solution is a factory which creates the actual instance in a build() method which must be the last in the chain:
User user = new UserFactory()
.firstName( "John" )
.familyName( "Doe" )
.address( address1 )
.address( address2 )
.build()
;
Modern languages like Groovy turn this into a language feature:
User user = new User( firstName: 'John', familyName: 'Doe',
address: [ address1, address2 ] )
You can implement Builders is a more concise manner. ;) I have often found writing Builders by hand tedious and error prone.
It can work well if you have a data model which generates your Data Value objects and their Builders (and marshallers). In that case I believe using Builders is worth it.
When you require a constructor (consider factories in a similar way) for an object, you force the code using your object to pass the essential requirements to the constructor. The more explicit the better.
You can leave the optional fields to be set later (injected) using a setter.