I have the following problem:
A framework generates a class from DB table, each table column is class variable(field).
The generated class has more than 30 fields and just one constructor with no parameters.
To create an instance of that class, I have to use 30 times some setters, which is invitation for inconsistencies.
I cannot use directly constructors with parameters or Builder pattern, as I cannot edit the generated class. What's the best way to approach this - Wrapper class, thread safe methods, a classic pattern?
You can create an external Builder class, that initialises all the fields to some default value whenever you create a new Object, and then behaves like a standard Builder.
I have solved this problem for myself by making a BeanBuilder class that uses reflection on the inside. You give it your bean and then call methods like startBean, value and similar to fill your bean with data, much like building an XML tree.
If you are in love with type safety, you can make a similar class for yourself that works specifically with that bean that you have.
You can use Builder pattern. For instance, if you have Car object with field power,weight,maxSpeed,color then you can use Builder like this:
CarBuilder{
private Car car = new Car();
public CarBuilder(int power,int weight){
car.setPower(power);
car.setWeight(weight);
}
public CarBuilder setColor(String color){
car.setColor(color);
return this;
}
public CarBuilder setMaxSpeed(int maxSpeed){
car.setMaxSpeed(maxSpeed);
return this;
}
public Car build(){
return car;
}
}
You can set mandatory fields in costructor and additional fields in settters. Also you can perform some checks in build method.
Related
I've been looking around the web for a while.
I'm trying to create an instance of a subclass dynamically, let me explain:
I have the following class:
Public abstract class Property
And a lot of sub class created from this class, for example the following two:
public class PropertyDns extends Property
Public class PropretyNetBios extends Property
I want the client to choose one of the subclass name, and then I need to create an instance of that class.
I'm going to have a lot of subclass that extends Property so switch-case statements will be exhausting:
So:
switch (user_input){
case "PropertyDns ": return new PropertyDns();
case "PropretyNetBios": return new PropretyNetBios();
.
.
.
}
will be terrible...
any ideas?
You can use one of the following two ways to achieve the result:
Create a factory method, which takes a String parameter, and based on the parameter, write up a switch to serve the required object.
The second option (and the recommended approach here) would be to dynamically create an instance from the class name using Class.newInstance
Using the second approach would make your solution easily extendable, and the addition of new classes won't need any structural changes.
A sample implementation of the second approach would be like:
public Property getProperty(String name) {
//Make sure the name contains full cannonical name of the class
return (Property) Class.forName(name).newInstance();
}
As I commented before, this problem can be solved with the Factory Pattern, if the number of classes is too large you can mix the Factory Pattern with an Annotation Processor to generate the factory. You need to create an annotation and a corresponding annotation processor.
Here is an example of the annotation you should create:
#Target(ElementType.TYPE) #Retention(RetentionPolicy.CLASS)
public #interface Property {
String name();
Class type();
}
Your property classes will look like this:
#Property(name="DnsProperty", class=Property.class)
public class DnsProperty extends Property{
...
}
You need to implement your own processor extending the class
javax.annotation.processing.AbstractProcessor
and register it at
/META-INF/services/javax.annotation.processing.Processor
The idea is to annotate each class to provide it's name, and generate the factory statements with the annotation processor, saving you from writing the exhausting switch-case statements. Explaining the annotation processors, as switch-case statements can be exhausting, so, you can read about it in the Java documentation, here is a blog post explaining annotation processors and here is the source code.
You need a Factory and a proper naming system for you classes(for example an enumeration), read about Factory pattern. This should work for you.
public class PropertyFactory {
public enum PropertyName {
DNS,
NET_BIOS
}
public Property createProperty(PropertyName name) {
switch (name) {
case DNS:
return new PropertyDns();
case NET_BIOS:
return new PropretyNetBios();
}
return null; //Or throw an exception
}
}
I have numerous constructors inside one of my Classes so I thought it would be a good idea to to implement Bloch's "Builder Pattern" (see http://www.informit.com/articles/article.aspx?p=1216151&seqNum=2) for one of the Classes (Spring Project).
It's quite possible, I have missed something as I am getting an "IllegalArgumentException" when running a Test Case against the Class. Does Spring allow for this type of stuff or shall I just opt for the conventional multiple constructor approach?
java.lang.IllegalArgumentException: No serializer found for class com.AllTweets$Builder and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.AllTweets["builder"])
at org.codehaus.jackson.map.ObjectMapper._convert(ObjectMapper.java:2502)
at org.codehaus.jackson.map.ObjectMapper.convertValue(ObjectMapper.java:2482)
at org.springframework.data.redis.hash.JacksonHashMapper.toHash(JacksonHashMapper.java:52)
at org.springframework.data.redis.hash.DecoratingStringHashMapper.toHash(DecoratingStringHashMapper.java:4
...
Class
public class AllTweets implements Serializable{
....
public Builder getBuilder() {
return new Builder();
}
public static class Builder {
private AllTweets build;
public Builder() {
build = new AllTweets();
}
public Builder isTweet(Tweet tweet){
build.id = tweet.getId();
return this;
}
public Builder isRetweet(Retweet retweet){
build.id = retweet.getId();
return this;
}
public AllTweets build(){
return build;
}
//Acessors
}
This exception doesn't have much to do with Spring. It only has to do with how Jackson automatically serializes your objects to JSON. You added a method getBuilder() to your class, and Jackson sees that as a rgular property of your bean that must be serialized, although it shouldn't be. So, choose another name for this method (like builder()), or annotate it with #JsonIgnore to make Jackson aware that this property must not be serialized.
That said, I really don't understand why this method is not static. You shouldn't have to create a new AllTweets object to be able to get a builder from it, to be able to build another AllTweets object. The method should thus be static, to be able to simply do
AllTweets result = AllTweets.getBuilder().isTweet(foo).isShare(bar).build();
And making it static will also solve the initial problem, because the getBuilder() method won't be considered as a bean property anymore by Jackson. See Google Guava for an example implementation of this pattern: note that the method is static, and is named builder().
Is Javascript-like prototyping anyhow achievable, even using Reflection? Can I wrap my object inside another one, just to extend its functionality with one or two more methods, without wiring all its original nonprivate methods to the wrapper class, or extends is all I get?
If you are looking for extension methods, you could try Xtend. Xtend is language that compiles to java code and eliminates boilerplate code.
The following text is stolen from the Xtend Docs for extensions:
By adding the extension keyword to a field, a local variable or a parameter declaration, its instance methods become extension methods.
Imagine you want to have some layer specific functionality on a class Person. Let us say you are in a servlet-like class and want to persist a Person using some persistence mechanism. Let us assume Person implements a common interface Entity. You could have the following interface
interface EntityPersistence {
public save(Entity e);
public update(Entity e);
public delete(Entity e);
}
And if you have obtained an instance of that type (through a factory or dependency injection or what ever) like this:
class MyServlet {
extension EntityPersistence ep = Factory.get(typeof(EntityPersistence))
...
}
You are able to save, update and delete any entity like this:
val Person person = ...
person.save // calls ep.save(person)
person.name = 'Horst'
person.update // calls ep.update(person)
person.delete // calls ep.delete(person)
I don't think you can do this in Java. You can though in Groovy, using metaclasses
String.metaClass.world = {
return delegate + " world!"
}
println "Hello".world()
I have data model classes that contain private fields which are meant to be read-only (via a getter function). These fields are set by my JPA persistence provider (eclipselink) during normal operation, using the contents of the database. For unit tests, I want to set them to fake values from a mockup of the persistence layer. How can I do that? How does eclipselink set these values, anyway?
Simplified example:
#Entity
class MyEntity
{
#Id
private Integer _ix;
public Integer ixGet()
{
return this._ix;
}
}
Can you just Mock the Entity itself, providing your own implemenations of the getters?
You could create an anonymous extension in your mock persistence layer:
MyEntity x = new MyEntity() {
public Integer ixGet() { return new Integer(88); }
};
You need to use the Reflection API. Use Class.getField() to get the field, then call setAccessable(true) on that field so that you may write to it, even though it is private, and finally you may call set() on it to write a new value.
For example:
public class A {
private int i;
}
You want to set the field 'i' to 3, even though it is private:
void forceSetInt(Object o, String fieldName, int value) {
Class<?> clazz = o.getClass();
Field field = clazz.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(o, value);
}
There are a number of exceptions that you will need to handle.
You can use a test library like Mockito to access objects internal state in read and write mode. For example with Mockito use:
//read
Integer i = Whitebox.getInternalState(myEntity,"_ix")
//Write
Whitebox.setInternalState(myEntity,"_ix", 123)
You can use a mocking framework like powermock to by pass encapsulation. In powermock you'd use Whitebox.setInternalState(..) to set a private member.
A less invasive method would be to mock the getter method. Whether this is feasible would depend on what else depends on the internal state but if it is enough, it's the cleaner solution.
Some methods I've used in the past:
Make _ix protected, create a subclass where you implement a setter
Make a constructor taking the value for _ix as a parameter
Use reflection
Another option, if you really hate to make things public, is to create a subclass for testing, and provide public access there.
You have a few options:
Create stubs to replace your entity (extract an interface first)
Use Reflection
Add a public setter for testing
Keep your tests within the package and use a default scope
For a bunch of useful techniques, have a look at Michael Feather's book, Working Effectively With Legacy Code
You can add constructor with parameter for your read-only variable. Don't forget to add a default (zero parameter) constructor.
#Entity
class MyEntity
{
#Id
private Integer _ix;
public MyEntity(Integer ix) {
_ix = ix;
}
public MyEntity() {
/*
* Default constructor
*/
}
public Integer ixGet()
{
return this._ix;
}
}
The constructor is a best way I think. If this entity has to be really readonly (not allowed to create new instances in production code at all) you can make constructor with package access and use it only within the tests. And there is a possibility that even if you make your default constructor private or with package access, your persistance provider still be able to work with such entity, but not sure though - check with eclipselink docs.
I better explain the question with an example.
I have an Interface Model which can be used to access data.
There can be different implementations of Model which can represent the data in various format say XMl , txt format etc. Model is not concerned with the formats.
Lets say one such implementation is myxmlModel.
Now i want to force myxmlModel and every other implementation of Model to follow Singleton Pattern.The usual way is to make myxmlModels constructor private and provide a static factory method to return an instance of myModel class.But the problem is interface cannot have static method definitions and a result i cannot enforce a particular Factory method definition on all implementation of Model. So one implementation may end with providing getObject() and other may have getNewModel()..
One work around is to allow package access to myxmlModel's constructor and create a Factory class which creates the myxmlModel object and cache it for further use.
I was wondering if there is a better way to achieve the same functionality .
Make a factory that returns
instances of your interface, Model.
Make all concrete implementations of the model package-private classes
in the same package as your factory.
If your model is to be a singleton, and you are using java
5+, use enum instead of traditional
singleton, as it is safer.
public enum MyXMLModel{
INSTANCE();
//rest of class
};
EDIT:
Another possibility is to create delegate classes that do all the work and then use an enum to provide all of the Model Options.
for instance:
class MyXMLModelDelegate implements Model {
public void foo() { /*does foo*/}
...
}
class MyJSONModelDelegate implements Model {
public void foo() { /*does foo*/ }
...
}
public enum Models {
XML(new MyXMLModelDelgate()),
JSON(new MyJSONModelDelegate());
private Model delegate;
public Models(Model delegate) { this.delegate=delegate; }
public void foo() { delegate.foo(); }
}
You can use reflection. Something like this:
public interface Model {
class Singleton {
public static Model instance(Class<? extends Model> modelClass) {
try {
return (Model)modelClass.getField("instance").get(null);
} catch (blah-blah) {
blah-blah
}
}
}
public class XmlModel implements Model {
private static final Model instance = new XmlModel();
private XmlModel() {
}
}
usage:
Model.Singleton.instance(XmlModel.class)
Actually, I don't like this code much :). First, it uses reflection - very slow, second - there are possibilities of runtime errors in case of wrong definitions of classes.
Can you refactor the interface to be an abstract class? This will allow you to force a particular factory method down to all implementing classes.
I used to ask myself the same question. And I proposed the same answer ;-)
Now I normally drop the "forcing" behavior, I rely on documentation.
I found no case where the Singleton aspect was so compelling that it needed to be enforced by all means.
It is just a "best-practice" for the project.
I usually use Spring to instanciate such an object,
and it is the Spring configuration that makes it a Singleton.
Safe, and so easy ... plus additionnal Spring advantages (such as Proxying, substituing a different object once to make some tests etc...)
This is more an answer to your comment/clarification to kts's answer. Is it so, that the real problem is not using the Singleton pattern but instead defining an eclipse (equinox) extension point schema that allows contributing a singleton?
I think, this can't be done, because everytime you call IConfigurationElement.createExecutableExtension you create a new instance. This is quite incompatible with your singleton requirement. And therefore you need the public default constructor so that everybody can create instances.
Unless you can change the extension point definition so that plugins contribute a ModelFactory rather than a model, like
public interface ModelFactory {
public Model getModelInstance();
}
So the extension user will instantiate a ModelFactory and use it to obtain the singleton.
If I guessed wrong, leave a comment and I delete the answer ;)