I wonder what is the patten in this code.
I was analyzing a library called web3j.
Here is the code for this source:
public interface FilterTopic<T>
{
#JsonValue
T getValue();
}
public static class SingleTopic implements FilterTopic<String>
{
private String topic;
public SingleTopic()
{
this.topic = null;
}
public SingleTopic(String topic)
{
this.topic = topic;
}
#Override
public String getValue() {
// TODO Auto-generated method stub
return topic;
}
}
public static class ListTopic implements FilterTopic<List<SingleTopic>>
{
private List<SingleTopic> topics;
public ListTopic(String… optionalTopics)
{
topics = new ArrayList<>();
for(String topic : optionalTopics)
{
if(topic != null) topics.add(new SingleTopic(topic));
else topics.add(new SingleTopic());
}
}
#Override
public List<SingleTopic> getValue() {
// TODO Auto-generated method stub
return topics;
}
}
You can see the FilterTopic interface. And it has several return values using the static class. What pattern is this like?
If you want to see the full code, look here
https://github.com/KoangHoYeom/Ethereum-JSONRPC-With-Java-Ex/blob/master/src/main/java/org/BlockChainService/domain/dto/Filter.java
Thank you for reading!
It's just a normal Object Oriented code and is using a simple inheritance. But if you mean how it can have different return values for the same method definition, then you need to take a look at a tutorial about Generics in Java.
As a short answer, the original method accepts a type as a parameter inside a pair of < and > (FilterTopic<T>). This T can be any type (e.g. Object, String, List, etc.), and you can see that the getValue() method also returns the same type (the T). You can use any character or name instead of T, it's just a placeholder (like a variable name).
Then each child class while implementing this interface, specifies the exact type name for this parameter. This means that the getValue() method of that class should return the exact same type. So the SingleTopic is defined using <String> then its getValue() method should return String. The ListTopic is defined using a list of SingleTopic items, then its getValue() must return a such a list.
You can read more about generics in java at following links:
Java - Generics - Tutorialspoint
The Basics of Java Generics
Related
I realize that it is not possible to derive from primitive objects as they are declared final. How do I work around this restriction? I am programming with the JPA Criteria API. Almost everywhere I handle with my own methods having Integer/String parameters to compare against entity fields representing database table row values. On any of these parameters I would like to accept QueryParameter<Integer> or QueryParameter<String>. Doing so I would have to create the method a second time accepting query parameters instead of the literals. However, thinking about value lists (as in the QueryBuilder's in(...) method) with permutating literals and query parameters, makes it hard or even impossible to implement.
Let us assume I had an entity Car with a method withFeatures(StringRepresentation ... features) and there would be literals and query parameters had derived from the same super-class StringRepresentation which itself would have be derived from the primitive type String. I would like to do so:
myCar.withFeatures("Seat Heating", "Metallic Color", "Trailer Hitch");
myCar.withFeatures(new QueryParam<String>("MyFavourit"));
myCar.withFeatures("Seat Heating", new QueryParam<String>("LoveThatColor"), "Trailer Hitch");
Has anyone an approach or even kind of a solution for this?
I'd use a builder pattern with one method for each type of criterion.
class Car {
private Set<String> features = new HashSet();
public Car withFeature(String f) {
features.add(f);
return this;
}
public Car withFeature(QueryParameter<String> q) {
features.add(q.getStringRepresentation()); // or whatever
return this;
}
...
}
So you can say:
myCar.withFeature("Seat Heating")
.withFeature(new QueryParam<String>("MyFavourit");
with permutating literals and query parameters, makes it hard or even impossible to implement
You could leverage CharSequence for strings, but I'm not sure that's a god idea...
import lombok.RequiredArgsConstructor;
public class Test {
public static void main(String[] args) {
withFeatures("test", new StringQueryParam("test2"));
}
#SafeVarargs
public final static <T extends CharSequence> void withFeatures(T ...params) {
// Wrap in StringQueryParam if not an instance of QueryParam<String>
}
interface QueryParam<T> {
}
#RequiredArgsConstructor
static class StringQueryParam implements QueryParam<String>, CharSequence {
private final CharSequence value;
#Override
public int length() {
return value.length();
}
#Override
public char charAt(int index) {
return value.charAt(index);
}
#Override
public CharSequence subSequence(int start, int end) {
return value.subSequence(start, end);
}
}
}
Having less verbose static factory methods (e.g. QueryParam.of, QueryParam.all, etc. for query params) mixed with builders or ways to combine them effectively could help.
e.g.
// Assuming Lists.union util method
withFeatures(Lists.union(
QueryParam.all("a", "b"),
QueryParam.of("c")
));
// With static imports
withFeatures(union(params("a", "b"), param("c"));
// With ParamsBuilder
withFeatures(ParamsBuilder.of("a", "b").add(QueryParam.of("c").build())));
Hopefully that gives you some ideas on how to design the API! You may as well use a more complicated, but flexible route where the entire criteria is just an AST so that QueryParam really just is a type of Expression in the AST allowing to create composites, etc. If you look at QueryDSL everything is a DslExpression and you have visitors to execute operations against the tree.
I spent some time to solve that problem taking in the hints from the Java Community so far.
Of course I am a follower of Java's concept of type safety (thanks to plalx). Hence, my solution will probably has to do with parameterized types.
And also I do admiring the concept of design patterns like many others (thanks to tgdavies). Hence, I use the builder pattern with one method for each type of criterion. I will accept to implement car feature methods for
using plain old literals of String
as well as specifying parameters of String
That is:
myCar.withFeatures("Seat Heating", "Metallic Color", "Trailer Hitch");
as well as specifying (let's say) query parameters or String parameters of some kind with a slightly more complex way by using a static method sp(...)
myCar.withFeatures(sp("MyFavourit"));
and of course a mixture of both, introducing another static method sr(...) for string representation:
myCar.withFeatures(sr("Seat Heating"), sp("LoveThatColor"), sr("Trailer Hitch"));
The mixture of both is important in cases where we want to use variable arguments in method signatures to specify those representations, in this case car features.
As one can see, it is almost the usage I stated above when posting this question.
How can I achieve this?
At first I designed an interface to implement my different String representations against:
public interface ValueTypeRepresentation<T> {
public Class<T> getClazz();
public QueryParameter<T> getQueryParameter();
public RepresentationType getRepresentationType();
public T getValue();
}
The methods are to determine whether the representation is a literal or a parameter, and to get the literal's value resp. the parameter itself to later on use its name.
The clazz member is to ease the Java Generic Type Inference purposes because I will be using parameterized types to implement different type representations. As I said, String ist just the starter of the show.
Then I designed an abstract class to derive the concrete classes of representations of different primitive objects from:
abstract class AbstractValueTypeRepresentation<T> implements ValueTypeRepresentation<T> {
private Class<T> clazz;
private RepresentationType representationType = RepresentationType.VALUE;
private QueryParameter<T> queryParameter;
private T value;
public AbstractValueTypeRepresentation(Class<T> clazz, T value) {
this.clazz = clazz;
this.representationType = RepresentationType.VALUE;
this.value = value;
}
public AbstractValueTypeRepresentation(QueryParameter<T> qp) {
this.clazz = qp.getClazz();
this.representationType = RepresentationType.PARAM;
this.queryParameter = qp;
}
#Override
public Class<T> getClazz() {
return clazz;
}
#Override
public QueryParameter<T> getQueryParameter() {
return queryParameter;
}
#Override
public RepresentationType getRepresentationType() {
return representationType;
}
#Override
public T getValue() {
return value;
}
}
To distinguish a literal of that type from the query parameter of that type, I introduced this enumeration:
public enum RepresentationType {
PARAM, VALUE;
}
Then I designed the first concrete representation, here for my StringRepresentation (derived from the abstract class above):
public class StringRepresentation extends AbstractValueTypeRepresentation<String> {
public static StringRepresentation sr(String s) {
return new StringRepresentation(s);
}
public static StringRepresentation sp(String name) {
return new StringRepresentation(new QueryParameter<String>(String.class, name));
}
public StringRepresentation(String value) {
super(String.class, value);
}
public StringRepresentation(QueryParameter<String> queryParameter) {
super(queryParameter);
}
}
Obviously this is easy to extend to representations of Integer, Float, LocalDate, etc.
First of all, sorry for the bad title. I don't know how to describe the problem in a few words (maybe not even in many)...
I am refactoring some settings in our system to be more abstract. The current solution has multiple tables in the DB, one for each settings area. In order to add a new setting, you'll need to extend the schema, the hibernate class, all transfer object classes, getters/setters, etc. I felt that this is violating OCP (open-closed principle), thus the refactoring.
I've spent some time coming up with ideas on how to implement such an abstraction. My favourite idea so far is the following:
1 enum for each settings area
1 enum value for each setting
Each setting is a SettingsDefinition<T> class using a generic type
A SettingsService is using static get/set methods with generic types
So for example, a settings area could be:
public enum SettingsABC{
A(new SettingDefinition<Integer>("A", 123)),
B(new SettingDefinition<String>("B", "Hello")),
C(new SettingDefinition<Boolean>("C", false));
private SettingDefinition settingDefinition;
SettingsABC(SettingDefinition settingDefinition) {
this.settingDefinition = settingDefinition;
}
public SettingDefinition getDefinition() {
return settingDefinition;
}
}
Where the SettingDefinition is the following:
public class SettingDefinition<T> {
private String name;
private T defaultValue;
public SettingDefinition(String name, T defaultValue) {
this.name = name;
this.defaultValue = defaultValue;
}
public String getName() {
return name;
}
public T getDefaultValue() {
return defaultValue;
}
}
And the service to get/set the values would be:
public class SettingsService {
public static <T> T getSetting(SettingDefinition setting) {
// hit db to read
// return value
}
public static <T> void setSetting(SettingDefinition setting, T value) {
// hit db to write
}
}
And the consumer would look something like this:
String value = SettingsService.getSetting(SettingsABC.B.getDefinition());
SettingsService.setSetting(SettingsABC.A.getDefinition(), 123);
My problem is that I cannot enforce a compiler type check between the generic type of the SettingDefinition inside SettingsABC and the generic type of get/set methods of the service. So in essence, I can do this:
Integer value = SettingsService.getSetting(SettingsABC.B.getDefinition());
Where B's definition is of type String.
Also, I can do this:
SettingsService.setSetting(SettingsABC.A.getDefinition(), "A");
Where A's definition is an Integer.
Is there any way to use generics to force these two different generic types match?
You can convert the enum to the class:
public final class SettingsABC<T> {
public static final SettingsABC<Integer> A =
new SettingsABC<>(new SettingDefinition<>("A", 123));
public static final SettingsABC<String> B =
new SettingsABC<>(new SettingDefinition<>("B", "Hello"));
public static final SettingsABC<Boolean> C =
new SettingsABC<>(new SettingDefinition<>("C", false));
private final SettingDefinition<T> settingDefinition;
// private constructor, so nobody else would instantiate it
private SettingsABC(SettingDefinition<T> settingDefinition) {
this.settingDefinition = settingDefinition;
}
public SettingDefinition<T> getDefinition() {
return settingDefinition;
}
}
This way individual constants will be typed. Now you can use the type arguments for SettingService as well:
public static <T> T getSetting(SettingDefinition<T> setting) {
...
}
public static <T> void setSetting(SettingDefinition<T> setting, T value) {
...
}
Although it's not an enum anymore, it can be used mostly in the same way. If you need other methods which are usually available in enum, you can mimic them like this:
public String name() {
return settingDefinition.getName();
}
#Override
public String toString() {
return settingDefinition.getName();
}
// and so on
I wanted to do overloaded method dispatching and Visitor pattern looked too much convoluted.
My stupid mind came up with something like below, and it works. Is it fine to follow something like this ?
An interface
public interface Value {
default public Integer getValue(){
return 1;
}
}
One can have multiple types of Value interface, for example like two Value interface implementations below.
class ConcreteValueA implements Value {
#Override
public Integer getValue() {
return 2;
}
}
class ConcreteValueB implements Value {
#Override
public Integer getValue() {
return 3;
}
}
and a service implementation with overloaded methods like below which perform operations based on input type.
public class ImplA implements Interface{
private final Function<ConcreteValueA, Optional<String>> handleConcreteA = this::handle;
private final Function<ConcreteValueB, Optional<String>> handleConcreteB = this::handle;
private final Map<Class<? extends Value>, Function> functions;
public ImplA(){
functions = new HashMap<>();
functions.put(ConcreteValueA.class, handleConcreteA);
functions.put(ConcreteValueB.class, handleConcreteB);
}
/**
* Overridden method
*/
#Override
public Optional<String> handle(Value input) {
Function function = functions.get(input.getClass());
return (Optional<String>)function.apply(input);
}
/**
* Overloaded method A
*/
public Optional<String> handle(ConcreteValueA input) {
return Optional.of(input.getValue()+":A");
}
/**
* Overloaded method B
*/
public Optional<String> handle(ConcreteValueB input) {
return Optional.of(input.getValue()+":B");
}
/**
* Test method
*/
public static void main(String [] args){
Interface service = new ImplA();
Value input = new ConcreteValueB();
Optional<String> optional = service.handle(input);
System.out.println(optional.orElse("Default"));
}
}
Prints 3:B, which what I wanted.
Yes, Double Dispatch via reflection is a common replacement of the Visitor pattern in Java (and other languages that support introspection).
However, the Visitor pattern is still useful to let users to extend closed hierarchies, ie add a new virtual function to all classes of a hierarchy without changing them.
I am looking for a good way to have different implementations of the same method which is defined in an interface but with different parameter types. Would this be possible?
In order to clarify this, suppose I have an interface Database and two implementing classes Database1 and Database2. Database has a method createNode(...) and another one modifyNode(...). The problem is that for Database1 the return type of the createNode method should be a long (the identifier). For Database2, however, it would be an object specific from the technology (in this case OrientDB but this doesn't matter too much, it is simply something that extends Object, of course). And also both create(...) return types should be used as one of modifyNode(...) parameters.
What I was thinking to do is:
`public interface Database {
public Object createNode(...);
public void modifyNode(Object id, ...);
...
}`
public class Database1 {
#Override
public Object createNode(...) {
...
long result = // obtain id of created node
return Long.valueOf(result);
}
#Override
public void modifyNode(Object id, ...) {
...
// use id as ((Long)id).longValue();
}
}
public class Database2 {
#Override
public Object createNode(...) {
...
SomeObject result = // obtain id of created node
return result;
}
#Override
public void modifyNode(Object id, ...) {
...
// use id as (SomeObject)id
}
}
I wanted to know if there is a better way to do this. Specially to avoid Long -> long and long -> Long conversions. I saw many similar questions here in StackOverflow but none of them were what I was looking for. Thank you very much in advance.
Here's an example of Generics
Database
public interface Database<T> {
public T createNode(...);
public void modifyNode(T id, ...);
...
}
Database1
class Database1 implements Database<Long> {
#Override
public Long createNode(...) {
...
long result = // obtain id of created node
return result;
}
#Override
public void modifyNode(Long id, ...) {
...
// use id
}
}
Database2
public class Database2 implements Database<SomeObject> {
#Override
public SomeObject createNode(...) {
...
SomeObject result = // obtain id of created node
return result;
}
#Override
public void modifyNode(SomeObject id, ...) {
...
// use id as (SomeObject)id
}
}
Btw, don't worry about autoboxing. You are using JDK >= 5 since there are #Override annotations.
I think you want Generic Methods.
Generic methods are methods that introduce their own type parameters.
This is similar to declaring a generic type, but the type parameter's
scope is limited to the method where it is declared. Static and
non-static generic methods are allowed, as well as generic class
constructors.
The syntax for a generic method includes a type parameter, inside
angle brackets, and appears before the method's return type. For
static generic methods, the type parameter section must appear before
the method's return type.
I wanted to try the factory pattern and was able to implement it, but when
generating for more than a few classes, i thought this will be ugly!! so any clarity or suggestions would be really appreciated...
My Superclass:
public abstract class Output {
public abstract void generate(Data dat); }
i got my other classes extending from Output like
public class generateXML extends Output{
.
.
.
}
My question is related to here:
public class generatorFactory(){
public Output generate(String str){
// or getting an Object as an argument like (Object obj)
if(str.equals("xml"){
return new generateXML();
}
else if.........
......
}
Is there any way we can determine the subclass type avoiding checking for each type??
You should consider replacing your if-else chain with a map.
Rather than having to write the code that checks for all the strings you want to support you just have a copule of lines to retrieve the element from the map.
You will, of course, need some more configuration code to put the items in the map, but that should be trivial.
Here it is a nice post about this topic (in PHP)
You can use newInstance() to instanciate a generator whose classname you've built from the parameter:
public Generator getGenerator (final String type)
{
final Class generatorClass = ClassLoader.getSystemClassLoader().loadClass("Generator"+type);
final Generator generator = (Generator) (generatorClass.newInstance());
return generator;
}
PS: I highly rate you to follow the rules of Java: if generateXML is a class, it should be written GenerateXML.
More over: take care by naming your classes. (1) An Object generateXML shouln'd extend Output, because it isnt' an output. (2) "GenerateXML" is a verb, i.e. an action. It is therefore not a correct word to name an object, but a method. You could name the object per example "XMLGenerator".
You can use Reflection.
Object generated = getClass().getMethod("generate" + type.toUpperCase()).invoke(this);
public Object generateXML();
public Object generateJSON();
public Object generateCSV();
You can use enum which can be passed to factory and return factory object based on enum passed. The only thing is you can not export it as API.
enum Type
{
XML {
#Override
public Object getFactory() {
// TODO Auto-generated method stub
return null;
}
};
public abstract Object getFactory();
}
If you have to expose it like API then you can do something like below.
interface IType {
public abstract Object getTypeFactory();
}
enum Type implements IType {
XML {
#Override
public Object getTypeFactory() {
// TODO Auto-generated method stub
return null;
}
};
}
And change Factory method implemetation to
public static Object getFactoryByType(String name) {
Type type = Type.valueOf(name);
return type.getTypeFactory();
}
Since you have to call new everytime I'm not sure you can bypass the branching process. Someone has to know what to give you back.
If it was for singletons you could initialize an HashMap "xml"=>generateXML singleton
After second though, you may modify your String attribute for differents Type classes MyTypeXML, MyTypeJSON, ...
and then use method with the same name but different type.
public Output generate(MyTypeXML xml) { // This will go for XML }
public Output generate(MyTypeJSON json) { // This will go for JSON }
But for factories, I'm not really against the if...else coding.