Usage of sling model - java

Which one of the following a better way of defining a sling model and why?
#Model(adaptables=Resource.class)
public interface MyModel {
#Inject
String getPropertyName();
}
OR
#Model(adaptables=Resource.class)
public class MyModel {
#Inject
private String propertyName;
}
Can you tell me a defined use case for using an interface as a model when all the methods are to be overridden in all the implementation classes?

Use an interface when you access values of the ValueMap without any need to provide an additional view of the data. Class based models are used, when you need to apply transformations to the data or add additional data (via OSGI services etc).

It strongly depends on the usage. In the case where you add the annotation to the getter you could also go with an interface instead of a class.
When you want to get a data attribute and manipulate it e.g. shorten a string or something, then it makes sense to inject it in a variable and then use a getter to return the shortened string.

Related

Java - correct way to delegate methods

My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
I want to define an interface with all my data needs, and classes that implement it (e.g. a class to get the data from a file, another for DB, etc...).
I want the rest of my project to not care where the data comes from, and not need to create any object to get the data, for example to call "DataSource.getSomething();"
For that I need DataSource to contain a variable of the type of the interface and initialize it with one of the concrete implementations, and expose all of its methods (that come from the interface) as static methods.
So, lets say the interface name is K, and the concrete implementations are A,B,C.
The way I do it today is:
public class DataSource {
private static K myVar = new B();
// For **every** method in K I do something like this:
public static String getSomething() {
return myVar.doSomething();
}
...
}
This is very bad since I need to copy all the methods of the interface and make them static just so I can delegate it to myVar, and many other obvious reasons.
What is the correct way to do it? (maybe there is a design pattern for it?)
**Note - since this will be the backbone of many many other projects and I will use these calls from thousands (if not tens of thousands) code lines, I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();" **
Edit :
I was offered here to use DI framework like Guice, does this mean I will need to add the DI code in every entry point (i.e. "main" method) in all my projects, or there is a way to do it once for all projects?
The classes using your data source should access it via an interface, and the correct instance provided to the class at construction time.
So first of all make DataSource an interface:
public interface DataSource {
String getSomething();
}
Now a concrete implementation:
public class B implements DataSource {
public String getSomething() {
//read a file, call a database whatever..
}
}
And then your calling class looks like this:
public class MyThingThatNeedsData {
private DataSource ds;
public MyThingThatNeedsData(DataSource ds) {
this.ds = ds;
}
public doSomethingRequiringData() {
String something = ds.getSomething();
//do whatever with the data
}
}
Somewhere else in your code you can instantiate this class:
public class Program {
public static void main(String[] args) {
DataSource ds = new B(); //Here we've picked the concrete implementation
MyThingThatNeedsData thing = new MyThingThatNeedsData(ds); //And we pass it in
String result = thing.doSomethingThatRequiresData();
}
}
You can do the last step using a Dependency Injection framework like Spring or Guice if you want to get fancy.
Bonus points: In your unit tests you can provide a mock/stub implementation of DataSource instead and your client class will be none the wiser!
I want to focus in my answer one important aspect in your question; you wrote:
Note - I insist on keeping it simple like "DataSource.getSomething();", I do not want anything like "DataSource.getInstance().getSomething();"
Thing is: simplicity is not measured on number of characters. Simplicity comes out of good design; and good design comes out of following best practices.
In other words: if you think that DataSource.getSomething() is "easier" than something that uses (for example) dependency injection to "magically" provide you with an object that implements a certain interfaces; then: you are mistaken!
It is the other way round: those are separated concerns: one the one hand; you should declare such an interface that describes the functionality that need. On the other hand, you have client code that needs an object of that interface. That is all you should be focusing on. The step of "creating" that object; and making it available to your code might look more complicated than just calling a static method; but I guarantee you: following the answer from Paolo will make your product better.
It is sometimes easy to do the wrong thing!
EDIT: one pattern that I am using:
interface SomeFunc {
void foo();
}
class SomeFuncImpl implements SomeFunc {
...
}
enum SomeFuncProvider implements SomeFunc {
INSTANCE;
private final SomeFunc delegatee = new SomeFuncImpl();
#Override
void foo() { delegatee.foo(); }
This pattern allows you to write client code like
class Client {
private final SomeFunc func;
Client() { this(SomeFuncProvider.INSTANCE); }
Client(SomeFunc func) { this.func = func; }
Meaning:
There is a nice (singleton-correctway) of accessing an object giving you your functionality
The impl class is completely unit-testable
Client code uses dependency injection, and is therefore also fully unit-testable
My program gets information from an external source (can be a file, a database, or anything else I might decide upon in the future).
This is the thought behind patterns such as Data Access Object (short DAO) or the Repository pattern. The difference is blurry. Both are about abstracting away a data source behind a uniform interface. A common approach is having one DAO/Repository class per business- or database entity. It's up to you if you want them all to behave similarly (e.g. CRUD methods) or be specific with special queries and stuff. In Java EE the patterns are most often implemented using the Java Persistence API (short JPA).
For that I need DataSource to contain a variable of the type of the
interface and initialize it with one of the concrete implementations,
For this initialization you don't want to know or define the type in the using classes. This is where Inversion Of Control (short IOC) comes into play. A simple way to archieve this is putting all dependencies into constructor parameters, but this way you only move the problem one stage up. In Java context you'll often hear the term Context and Dependency Injection (short CDI) which is basically an implementation of the IOC idea. Specifically in Java EE there's the CDI package, which enables you to inject instances of classes based on their implemented interfaces. You basically do not call any constructors anymore when using CDI effectively. You only define your class' dependencies using annotations.
and expose all of its methods (that come from the interface)
This is a misconception. You do want it to expose the interface-defined method ONLY. All other public methods on the class are irrelevant and only meant for testing or in rare cases where you want to use specific behavior.
as static methods.
Having stateful classes with static method only is an antipattern. Since your data source classes must contain a reference to the underlying data source, they have a state. That said, the class needs a private field. This makes usage through static methods impossible. Additionally, static classes are very hard to test and do not behave nicely in multi-threaded environments.

Can a JavaBean have methods besides getters and setters?

According to definitions I find in the internet a JavaBean is a Java class that satisfies these conditions:
All instance attributes are private
All instance attributes have public getters and setters
The class has a parameterless constructor
The class implements the Serializable interface
What I would like to know is that if I add method to a Javabean can we still call it a Javabean?
For exemple can we say that the following class is a JavaBean?
public class Person implements Serializable {
private String name;
public Person(){}
public String getName(){...}
public void setName(String name){...}
public void sayHello(){}
}
Yes, Java Beans can definitely have behavior. Java Bean classes without additional methods have very limited applicability, because they encapsulate data devoid of useful behavior.
Oracle mentions this in one of their tutorials on Java Beans:
A bean's methods are the things it can do. Any public method that is not part of a property definition is a bean method. When you use a bean in the context of a builder tool like NetBeans, you can use a bean's methods as part of your application. For example, you could wire a button press to call one of your bean's methods.
Yes, java beans can have additional functionality. The convention was introduced to access properties in a structured way and add functionality like vetoing. It is used for example for GUI components in swing, where the bean mechanism is used to configure the GUI elements. Especially in GUI editors there was the need to dynamically access unknown properties. And of course, these GUI components have lots of functionalities. What you get if you restrict to your set of conditions is a DTO (data transfer object), that only transports data but has no additional functions.

Best approach for creating URLs in Spring

Let's say we have controllers with URL mappings like movie/{id}-{title}, actor/{id}-{name}, etc. These mappings identify some objects in our app, mostly entities - we can say it's a RESTful service.
I'm looking for a solution as to where I should put methods responsible for creation of those URIs. I think that creating them in multiple JSP files and some other places (redirection, etc.) is redundant.
First, what I thought about was creating some interface with method public URI getURI() that classes that will be used in controllers will implement. But, in my opinion, that would involve too much into entity - I prefer entities just to represent data and contain only methods to change state.
My second idea was to create a URIService with overloaded methods like URI getURI(Movie m) and URI getURI(Actor a), but there will be a problem with the choice of overloading method at compile time. For example, in EL in JSP that wouldn't work well, as the solution would be naming methods differently.
I don't want to reinvent the wheel, so maybe you know or use some solution to that problem?
How enterprisey do you want the solution to be? (I'm just half kidding)
Here's a solution: Have a service that has a method like URI getURI(Object o). This method will check if the object passed belongs to a class with an annotation that specifies the URI path. Example annotation:
public #interface PathTemplate {String value();}
Example class with the annotation:
#PathTemplate("/movie/{title}-{id}")
public class Movie {
private int id;private String title;
// getters and setters too
}
Now, the getURI method will see that the parameter object's class has a PathTemplate annotation and will interpolate the parameters using bean introspection. Voila! Expandable and relatively decoupled URI generation.

How should i object model class blueprints and concrete classes?

This is not a question about what is a class or what is an object.
I am trying to identify a design pattern, for reuse.
I have a class blue print which consists of a Map keyed with the field name and a value of properties of the field. This map values describe the fields of a particular class.
class FieldDescriptor {
public FieldDescriptor(String name, int length, boolean isKey) {
....
}
...
}
class ConcreteClass {
final public static Map<String, FieldDescriptor> fields;
static {
Map<String, FieldDescriptor> myFields = new HashMap<String, FieldDescriptor>();
myFields.put("PERSON_CODE", new FieldDescriptor("PERSON_CODE", 10, true);
myFields.put("FUN_FUN_FUN", new FieldDescriptor("FUN_FUN_FUN", 6, false);
myFields.put("JEDI_POWER_RATING", new FieldDescriptor("JEDI_POWER_RATING", 9000, true);
fields = Collections.unmodifiableMap(myFields);
}
private String personCode;
private String funFunFun;
private String jediPowerRating;
public void setPersonCode(String personCode) {
this.personCode = transformField(fields.get("PERSON_CODE"), personCode);
}
...
}
The whole reason for the maddness is the transformField call on the setters. It is central to why I have created the map.
However I would like to abstract this away from my class as I would like to build more classes this way and be able to refer to the map generically or via an interface.
I feel strongly that the Map should be encapsulated in a seperate class! However, how will instanciation of the ConcreteClass occur?
Can anyone identify a suitable design pattern?
I am not sure if i do understand your question. But if my understanding is correct, I would probably leverage reflection and an instance of the object, rather than introducing a custom Class called FieldDescriptor. Then again I do not know your complete use case, So I might be wrong.
So this is my solution briefly:
Each class will have to have a default static field called defaultInstance. defaultInstance would be of the same type as the Class itself. If I were using a framework like spring, I will try to leverage a framework callback method, to populate the defaultInstance (to me concise, if the lifecycle of the object is managed). The idea is to have an external Component responsible for providing each class with its defaultInstance. (Dynamic Injection ??).
Once the class needs access to value stored in default instance, It could use Reflection API or a wrapper like Apache BeanUtils to get Individual Field Name and value.
I see that you have a boolean field called isKey. If you need this information at runtime, you can use custom annotation to indicate some fields as Key and use isAnnotation Present to implement your branch logic.
So at the end of it call, you just need to have an attribute called defaultInstance in each class. Have a single component, that is responsible for populating this object. ( to make it configurable, you can store information in a property file or db like sqllite). Use Dynamic Injection or AOP if you could (so that its nonintrusive) and use Apache BeanUtils or Reflection API directly to get the information. (even this logic should be abstracted as a separate component).
It looks like the only reason you want all the extra complexity of field definitions is so you can relate your fields with their associated column attributes in the database table. You should not have to write this yourself - use a persistence framework like Spring or Hibernate to do the job for you. They use reflection internally, and help keep your data transfer objects (DTOs) clean and easy to maintain.

Interfaces and #RequestBody

I'm currently working on a project which allows users to book (via the web) the use of a chosen resource for a given period of time. In this program I am trying to keep with Spring's philosophy (and the general best practice) of programming to interfaces and as such I try to use interfaces anywhere where functionality is repeated among concrete classes.
One interface I have created is called a BookableResourceController which specifies the methods needed by a controller to handle the minimum required functionality for any type of resource to be booked. I also make use of a second interface, BookableResource, which identifies which objects model a resource that is allowed to be booked through the application.
The problem I am currently running into is that a few of the methods defined by BookableResourceController use the #RequestBody mapping to convert a JSON object into a method parameter, and since Jackson can only convert JSON into "SimpleType" objects, I receive an error if I specify the input parameter to be a BookableResource.
#RequestMapping(value="/delete.html", method = RequestMethod.POST)
public ModelAndView processDeleteResource(
#RequestBody BookableResource resource);
Can not construct instance of
org.codehaus.jackson.map.type.SimpleType,
problem: abstract types can only be
instantiated with additional type
information
From what I can tell this error means that I will need to define a specific implementation of BookableResource, meaning I will most likely need to exclude these methods from the interface even though any controller that is to be used for this purpose will require those methods.
What I am asking is if anyone knows a way to define an interface as the object that is expected from an #RequestBody mapping using JSON, or does anyone have any suggestions of how to structure my contoller interface in order to include these methods?
Cheers
I'm not sure it would work, but you can try to make it generic:
public interface BookableResourceController<R extends BookableResource> {
#RequestMapping(value="/delete.html", method = RequestMethod.POST)
public ModelAndView processDeleteResource(#RequestBody R resource);
}
Additional way to go that can be used is to annotate interface with Jackson annotation:
#JsonDeserialize(as=BookableResourceImp.class)
(possibly using mix-in annotations if one does not want to add it directly in interface class)
EDIT: Another possibility is to use SimpleModule method addAbstractTypeMapping() to specify implementation type. This avoids linkage from interface to implementation, and may (or may not) be more convenient way to register this aspect.

Categories

Resources