This is again, I guess, a 'best practices' question because i can think of some inelegant ways of getting my use case implemented.
My use case is as follows
Im writing a MethodManager(sort of) module which helps in the end user dealing with actual method(function) calls through a UI.
For this specific purpose i have a methodDefinition class which is an object form of what a method(function) looks like to my system.
A brief overview of what my methodDefinition's members look like is as follows
methodName -- String
methodInputs -- ArrayList<String>
methodResultType -- enum(STRING,MAP,LIST)
methodResult -- <<variable, on the basis of methodResultType>>
Now methodResult is variable and can be any of String, Map or List based on what methodResultType is set as.
I have created a MethodResultType class to account for methodResultType and it looks as follows
public enum MethodResultType {
LIST,
MAP,
STRING;
}
Now i know i have to write a class to account for methodResult and its variable nature based on methodResultType but cant think of a non botched up way to.
Any suggestions/ pointers in this regard would be greatly appreciated.
Thanks
p1ng
List, Map and String have a common ancestor class: java.lang.Object. methodResult can thus be an Object.
You could also wrap the result and its type into a MethodResult object, that would provide methods such as getType(), getValueAsString(), getValueAsList() and getValueAsMap(). These last three methods would throw an IllegalStateException if the type of the value is not the type returned by the method.
Related
I have a class for templating HTML selectors called Selectors.
In it I have named the fields name and age and the corresponding getters getName() and getAge().
Now it may seem a little confusing on its own but when given the class context I sort of believe that it's clear that you are getting the selector value and not the value of what's beign selected (i.e the person's name). For example:
Selectors webPageSelectors = new Selectors()
nameSelector = webPageSelectors.getName()
Is this clean and clear or should I add kind of repetetive words to field names and getters like nameSelector and getNameSelector()? Or perhaps something like this: webPageSelectors.getForName()? where the field is named forName (as if 'selector for name')? Thanks!
I think the code is clear if you know what it is intended to do.
However if you are worried, you can always use JAVA-DOC to provide clear documentation as to what each function does. This helps a lot in development teams.
Plus. is nameSelector of type Selector ? if so, then yes renaming the attributes in the Selectors class to include the type is much easier to understand. If you decide to do the latter, just make sure you don't do it to primitive type attributes.
This is just an opinion, you are free to code however you like.
I'm quite new in Java and need some help implementing the following:
In a mongodb-instance I save follwing data-structure:
{
name: String,
type: String // or anything else that might make this task easier
data [Array of objects]
}
The data structure of the data field depends of the type of the document.
The type also declares a certain Class, that handles populating and parsing the data.
My idea of accomplishing something like this with my current knowlegde would be to have a HashMap<String, Class> and then registering the type and the appropriate class.
Another way (which I don't know yet how to implement) would be to store the excat classname as the type and then trying to cast this string to a Class, but since the HashMap-way would probably be easier I thought I'd rather try this way.
What would be a good approach solving this problem?
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).
What would you use if you wanted to pass a list of options into a function?
For example, if you have an interface to a server:
public interface Server {
public void authUser(String username, String password, <xyz> options);
}
What structure would use use for to pass a set of options? Something like a HashMap?
The reason I'm saying that it comes from tunnel vision is because I feel that this goes against Java standards. Java has method overloading. So if I get flames for raising the question I understand. But overall, maybe in different cases, would you ever pass bulk data in some collection and, if yes, which one?
Option1 : If you are choosing any collections like List or Set these are specific to an object . I mean,
Lets Assume, Set sets = new HashSet();
If I want 5 Object of different different class having no relationship to be send, then It would be very difficult to recognize that which Object is belong to which class while Iteration. So, I wont recommend Collections.
Option2 : If you are choosing Map, the same above problem may occurs while getting the Object Dynamically. So, This Options is also not recommended.
Option3 :
Why cann't you create your own DTO and in that DTO place your reqyired datastructure and pass it over.
If you want 5 different Object to be pass then, you can pass. If all are of same type then you may use Collection or array or Variable Arguement based on your scenerio.
I think anything Serializable is exactly the thing. If you can serialize the object, then you can pass (store, transmit...) it, passing it's properties in bulk. What format of serialized data to choose, is another question.
It depends on the data you want to pass.
You can use a map(hashmap) if you are passing key-value pairs.
If it is just a list of diffrent object, you can use List(ArrayList)
Other option is to create DTO(data transfer object) with getter and setter methods.
You may want to take a look at VARARGS feature that was introduced in JAVA5.
I'd suggest a Map [HashMap] as you can then access the argument values via their Keys.
If I have a form-backing object that has a complicated object tree -- say a Person that has a Contact Info object that has an Address object that has a bunch of Strings -- it seems that the object needs to be fully populated with component objects before I can bind to it. So if I'm creating a new Person, I need to make sure it has all the component objects populated off the bat, and if I'm retrieving a Person from the database, I need to make sure that any objects that aren't populated from the database get populated with empty objects.
First question, of course -- am I correct in my assumptions above? It does seem that if I try to bind to person.contactInfo.homeAddress.street and there is no ContactInfo, I get a null pointer exception.
Second, what's the best way to initialize my object. I can think of a couple of approaches. One is to initialize all member objects at declaration:
public class Person {
String name;
ContactInfo contactInfo = new ContactInfo();
//getters, setters, etc.
}
public class ContactInfo {
String phone;
Address homeAddress = new Address();
}
and so forth.
Another approach is to have a PersonFactory that initializes everything (or to have a factory method Person.getInstance that initializes everything).
In the case of retrieving a Person from the database, the first approach will solve the issue (i.e. if this particular person doesn't have an address in the database, the object will still have an Address), but this will mean creating each object twice. Not sure how to handle this otherwise, except to make the DAO explicitly populate everything even if nothing has been retrieved from the database. Or to give the factory a method to go through the object and "fill in" anything that's missing.
Suggestions?
Call it overkill if you like, but what we actually ended up doing was to create a generic factory that will take any object and use reflection to (recursively) find all the null properties and instantiate an object of the correct type. I did this using Apache Commons BeanUtils.
This way you can take an object that you may have gotten from various sources (a DAO, deserialization from XML, whatever), pass it through this factory, and use it as a form-backing object without worrying that something you need for binding may be null.
Admittedly, this means instantiating properties that we may not need for a given form, but in our case that doesn't typically apply.
I would generally make sure objects are fully initialized - it makes using the object that much simplier and avoids you scattering null checks throughout your code.
In the case you give here I'd probably put the initialization in the getter so the child object is only instantiated when it's actually going to be used, ie: when the getter is called and then only if it's null.
In terms of loading from the database with one-to-one relationships I'd normally do the join and load the lot. The performance impact is typically minimal but you should be aware that there may be one.
When it comes to one-to-many relationships I normally go for lazy loading. Hibernate will take of this for you, but if you're rolling your own then you just need a custom implementation of List that calls the appropriate DAO when any of the methods relating to its contents are called.
The one exception to this behavior with one-to-many relationships is when you've got a list of parent objects that you intend to iterate over and for each parent you want to iterate over its children. Obviously the performance would suck because you'd be making a n + 1 calls to the DB when you could actually do it with 2 calls.
I guess you are talking about something like < form:input path="person.contactInfo.homeAddress.street"/> ?
Not clear for me but assuming i'm right :) :
1) Yes, When you write person.contactInfo.homeAddress.street , read person.getContactInfo().getHomeAddress().getStreet(). If ContactInfo or HomeAddress or Street objects are null, invocation of one of their method raises a NullPointException.
2)I usually initializes member objects at declaration, just like in code snippet. Don't see the benefit of factory class to do the job if initialization values are inconditionnal.
I don't clearly see the problem where you are forced to create a Person twice... but i may be tired ;)
I've gone with the Factory method approach (not a fan of using a seperate class for it, to me it makes more sense to have it in a static method so it's all in one place). I have something like -
public static Person getInstanceForContactInfoForm() {
ContactInfo contactInfo = ContactInfo.getInstanceForContactInfoForm();
Person person = new Person(contactInfo);
// set whatever other properties you need for Person
// just enough to 1-render the form and 2-avoid any exceptions
return person;
}
If I'm loading the Person from the database, I have a method in the Person class called something like "initalizeForContactInfoForm" or something. After loading the Person from the database, I'll call this method in the Service layer in the method that is called by the Spring MVC method which returns the Form Backing Object.
I don't think this is a really a convention, it's just an approach I cooked up on my own. I don't really see what any drawbacks are so if somebody disagrees please let me know...