public interface UnivariateOperator<T> {
public TimeSeries<T> operateOn(TimeSeries<T> timeseries);
}
public class SamplingOperator<T> implements UnivariateOperator<T> {
#Override
public TimeSeries<T> sample(TimeSeries<T> timeseries) {
...
}
}
Is there a way to use wildcards so the sampling operator can work with any type? I don't really want to have to specify the type for the sampling operator...it should work with any typed timeseries.
What if you did something like this:
public class SamplingOperator<T> implements UnivariateOperator<T> {
private SamplingOperator(){
}
#Override
public TimeSeries<T> sample(TimeSeries<T> timeseries) {
...
}
public static SamplingOperator<? extends Object> getInstance() {
return new SamplingOperator<Object>();
}
}
This ensures that any instance of SamplingOperator will be able to accept any type of TimeSeries as an argument to its sample method.
There are probably better solutions out there, but this one will work.
You can't, because you need to specify the generic of UnivariateOperator. If you just want a generic method that samples TimeSeries, you will need something like
public class TimeSeriesSampler {
public static <T> TimeSeries<T> sample(TimeSeries<T> timeseries) {
...
}
}
but if you want a SamplingOperator to implements UnivariantOperator, you will need to specify the generic. If you still don't want to specify, you could use something as
public class SamplingOperator implements UnivariateOperatior<Object> {
private SamplingOperator(){
}
public <T> TimeSeries<T> sample(TimeSeries<T> timeseries) {
return null;
}
#Override
public TimeSeries<Object> operateOn(TimeSeries<Object> timeseries) {
...
}
}
but you will lose the power of the generic. Another way is
public class SamplingOperator<S> implements UnivariateOperatior<S> {
private SamplingOperator(){
}
public <T> TimeSeries<T> sample(TimeSeries<T> timeseries) {
return null;
}
#Override
public TimeSeries<S> operateOn(TimeSeries<S> timeseries) {
return timeseries;
}
}
but it "smells" bad, as the sample method gives a feeling of a class method, instead of an instance one. It's your choice what's bst to do.
implements UnivariateOperator<Object>
Related
I have the following scenario:
public abstract class BaseTask{...}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public interface TaskService<T extends BaseTask>{
void process(T task);
}
#Service #Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
}
#Service #Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{
}
public class ProcessingService{
#Autowired #Qualifier("taskServiceA")
private TaskService<TaskA> taskAService;
#Autowired #Qualifier("taskServiceB")
private TaskService<TaskB> taskBService;
public void process(Order o){
BaseTask task = o.getTask();
getTaskService(o).start(task);
}
private <T extends BaseTask> TaskService<T> getTaskService(Order o){
if("atype".equals(o.type)){
return (TaskService<T>) taskAService;
} else if("btype".equals(o.type)){
return (TaskService<T>) taskBService;
}
}
}
Update: I have reworded the question because the answers I was getting was not what I was looking for.
My questions is related to the getTaskService method.
Why do I need to cast the return value like this
return (TaskService) taskAService;
Is there another way to implement the getTaskService() method without having to do the cast?
I will really appreciate if someone can provide some explanation or better implementation for the getTaskService method.
How about this?
No need of any if conditions.
Later if someone does add another implementation of BaseTask they don't have to change any other code.
Also I recommend changing "atype" to Enum and using Map<EnumTask, ? extends BaseTask> serviceMap; instead of String.
Your final invocation of Tasks can be without any checks
#Service
class ProcessingService {
#Autowired
private TaskServiceManager taskServiceManager;
public void process(Order o){
taskServiceManager.getServiceTask(o.type).start(task);
}
}
Other classes
enum ServiceEnum {
TaskA,
TaskB
}
public class TaskA extends BaseTask {....}
public class TaskB extends BaseTask {....}
public abstract class TaskService<T extends BaseTask>{
public TaskService(ServiceEnum serviceEnum, TaskServiceManager taskServiceManager) {
taskServiceManager.registerTask(serviceEnum, this);
}
void process(T task);
}
#Service #Qualifier("taskServiceA")
public class TaskServiceA<TaskA> implements TaskService<TaskA>{
#Autowired
public TaskA(TaskServiceManager taskServiceManager) {
super(ServiceEnum.TaskA, taskServiceManager);
}
}
#Service #Qualifier("taskServiceB")
public class TaskServiceB<TaskB> implements TaskService<TaskB>{...}
#Service
class TaskServiceManager {
Map<ServiceEnum, ? extends TaskService> serviceMap;
public <T extends TaskService> void registerTask(ServiceEnum serviceName, T task) {
if(serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is already in the Map");
}
serviceMap.put(serviceName, task);
}
public <T extends TaskService> T getServiceTask(ServiceEnum serviceName) {
if(!serviceMap.containsKey(serviceName)) {
throw new IllegalArgumentException("ServiceName is not Registered");
}
return serviceMap.get(serviceName);
}
}
Because type T is resolved wherever the method is used. The following statement is valid:
TaskService<TaskA> s = getTaskService(o);
So is:
TaskService<TaskB> s = getTaskService(o);
So within the method getTaskService, you don't know much about T.
The correct way to do this would be:
private TaskService<? extends BaseTask> getTaskService(Order o) {
if ("atype".equals(o.type)) {
return taskAService;
} else if ("btype".equals(o.type)) {
return taskBService;
} else {
return null;
}
}
The assignment above would have to become:
TaskService<? extends BaseTask> s = getTaskService(o);
I'm developing a database application for android devices.
First thing I need to do is creating the data access layer.
For this I want to use DAO-Pattern with abstract factories.
For all DAOs i have one Interface witch contains the declaration that all data object needs to implement. (in my case: IDataObject)
The specific DAOs are all represented by its own interface, extending the base interface of all DAOs.
base interface:
public interface IDataObject {
public IDataId getId();
public void write() throws MyDataWriteException;
public void validate() throws MyDataValidException;
}
a extensions:
public interface IDataSample1 extends IDataObject {
public void setNotice(String notice);
public String getNotice();
public void setDate(Date date);
public Date getDate();
}
To create an data object I want use abstract to use abstract factories, something like:
public interface IDataFactory<Template extends IDataObject> {
public List<Template> getAll();
public Template get(IDataId id);
public List<Template> getList(DataAccessArgument arg);
public List<Template> getList(List<DataAccessArgument> argList);
}
and the implementation:
public class DataSample1Fac implements IDataFactory<IDataSample1> {
public DataSample1Fac () {
}
public List<IDataSample1> getAll() {
return null;
}
public IDataSample1 get(IDataId id) {
return null;
}
public List<IDataSample1> getList(DataAccessArgument arg) {
return null;
}
public List<IDataSample1> getList(List<DataAccessArgument> argList) {
return null;
}
}
I don't get any error so far, but now I want to implement an factory builder:
public class DataFactoryBuilder {
private DataFactoryBuilder() {
}
public static<T extends IDataObject> IDataFactory<T> getFactory(){
if (T instanceof IDataSample1)
return new DataSample1Fac();
return null;
}
}
I get following errors(line 8):
T cannot be resolved to a variable
and (line 9)
Type mismatch: cannot convert from DataSample1Fac to IDataFactory<T>
Don't know how to fix this, any suggestions?
I would refactor Your's DataFactoryBuilder to something like that:
class DataFactoryBuilder {
private DataFactoryBuilder() {
}
public static IDataFactory<? extends IDataObject> getFactory(Class<? extends IDataObject> clazz){
if (IDataSample1.class.isAssignableFrom(clazz)) {
return new DataSample1Fac();
}
return null;
}
}
I got following solution:
public static <T extends IDataObject> IDataFactory<T> getFactory(Class<T> type) {
if (IDataSample1.class.isAssignableFrom(type)) {
DataSample1Facfac = new DataSample1Fac();
return (IDataFactory<T>) fac;
}
}
but i get an warning on: return (IDataFactory) fac;
Type safety: Unchecked cast from DataSample1Fac to IDataFactory<T>
I think that is not a problem, I just have to supress it
I am trying to design a factory for a pluggable interface. The idea is that once you have your factory instance, the factory will return the appropriate subclasses for that particular implementation.
In this case, I am wrapping a third party library that uses a String to represent an ID code, rather than subclasses. Therefore, in the implementation that wraps their library, every implementation class has a method getCode() that is not explicitly required by the interface API. I am using an enum to store this mapping between codes and interface classes.
In nearly all cases, the getCode() method is not needed. However, in just a few situations in the implementation package, I need access to that method. Therefore, my problem is that I would like to have the Factory implementation's signature tell callers that the getCode method exists if they have a reference to the specific Factory implementation.
What follows is a lot of code in my best-effort attempt to digest the situation into an sscce. I know it's very long, but it's simpler than it seems, and one of the words in sscce is "complete".
Public API:
public interface Factory {
public <T extends IFoo> T makeIFoo(Class<T> klass);
}
public interface IFoo {
void doSomething();
}
public interface IFooBar extends IFoo {
void doBarTask();
}
public interface IFooBaz extends IFoo {
void doBazTask();
}
Sample use case:
public class SomeClass {
private Factory myFactory;
public void doSomething() {
IFooBar ifb = myFactory.create(IFooBar.class);
}
}
SSCCE version of implementation:
interface ICode {
String getCode();
}
abstract class BaseCode implements IFoo, ICode {
private String code;
BaseCode(String code) {
this.code = code;
}
#Override
public String getCode() {
return code;
}
#Override
public void doSomething() {
System.out.println("Something");
}
}
class FooBarImpl extends BaseCode implements ICode, IFooBar {
FooBarImpl(String code) {
super(code);
}
#Override
public void doBarTask() {
System.out.println("BarTask");
}
}
class FooBazImpl extends BaseCode implements ICode, IFooBaz {
FooBazImpl(String code) {
super(code);
}
#Override
public void doBazTask() {
System.out.println("BarTask");
}
}
Enum codemapper:
static enum CodeMap {
FOOBAR ("A", IFooBar.class) {
FooBarImpl create() { return new FooBarImpl(getCode()); }
},
FOOBAZ ("B", IFooBaz.class) {
FooBazImpl create() { return new FooBazImpl(getCode()); }
};
private static Map<Class<? extends IFoo>, CodeMap> classMap;
static {
classMap = new HashMap<Class<? extends IFoo>, CodeMap>();
for(CodeMap cm : CodeMap.values()) {
classMap.put(cm.getFooClass(), cm);
}
}
private String code;
private Class<? extends IFoo> klass;
private CodeMap(String code, Class<? extends IFoo> klass) {
this.code = code;
this.klass = klass;
}
String getCode() {
return code;
}
Class<? extends IFoo> getFooClass() {
return klass;
}
static CodeMap getFromClass(Class<? extends IFoo> klass) {
return classMap.get(klass);
}
abstract BaseCode create();
}
Sample use case within implementation package:
public class InternalClass {
CodeFactory factory;
public void doSomething() {
FooBarImpl fb = factory.makeIFoo(IFooBar.class);
}
}
Attempt at factory:
This does not specify that the return will always implement ICode. But the passed-in interface class DOESN'T implement ICode, that's the whole point.
class CodeFactory implements Factory {
#Override
public <T extends IFoo> T makeIFoo(Class<T> klass) {
CodeMap map = CodeMap.getFromClass(klass);
if (map == null) return null; // Or throw an exception, whatever, SSCCE
return (T) map.create();
}
}
What should I do?
I realized I was making this too complicated. If I'm going to implement a factory method for each enum instance, I may as well just have separate factory methods for each interface.
public interface Factory {
IFooBar createFooBar();
IFooBaz createFooBaz();
}
class CodeFactory implements Factory {
public FooBarImpl createFooBar() {
// etc.
}
}
Of course now I have to change the Factory API if there are ever new interfaces, but I expect that will be rare.
A possible solution would be defining a wrapper that implements IFoo and the getCode() method, and your method would return the intended class in one of such wrappers.
If the wrapped instance has a getCode implemented, the wrapper would return its value, return it, otherwise return null.
I have an third-party RPC-API that provides an interface similar to that of java.sql.ResultSet (for reading values) and java.sql.PreparedStatement (for writing values). Assume it looks something like this:
public interface RemoteDeviceProxy {
public void setBoolean(Boolean value);
public void setInteger(Integer value);
// ...
public Boolean getBoolean();
public Integer getInteger();
// ...
}
I want to write a wrapper for this API that uses generics to create instances of specific types:
public class <T> RemoteVariable {
private final RemoteDeviceProxy wrappedDevice;
public RemoteVariable(RemoteDeviceProxy wrappedDevice) {
this.wrappedDevice = wrappedDevice;
}
public T get() {
// should call wrappedDevice.getBoolean() if T is Boolean, etc.
// how to implement?
}
public void set(T newValue) {
// should call wrappedDevice.setBoolean(newValue) if T is Boolean, etc.
// implement using instanceof
}
}
How can I implement the getter in my generic wrapper? I have found this answer which explains a similar scenario in depth, but I am not able to transfer this to my problem. Specifically, when I write this:
public T get() {
Type[] actualTypeArguments = ((ParameterizedType) getClass())
.getActualTypeArguments();
}
I get a compiler error saying I cannot cast to ParameterizedType, and I do not understand why. Can anyone explain how to achieve this?
Here is one way:
public class <T> RemoteVariable {
private final RemoteDeviceProxy wrappedDevice;
private final Class<T> clazz;
public RemoteVariable(RemoteDeviceProxy wrappedDevice, Class<T> clazz) {
this.wrappedDevice = wrappedDevice;
this.clazz = clazz;
}
public T get() {
if(clazz == Boolean.class){return clazz.cast(wrappedDevice.getBoolean());}
else if(clazz == Integer.class){return clazz.cast(wrappedDevice.getInteger());}
// ...
}
// ...
}
I thought over this quite a while and finally came up with a different approach:
First I added a getter to you RemoteVariable class:
protected RemoteDeviceProxy getWrappedProxy() {
return wrappedProxy;
}
Second I created a builder interface that will be used by a factory later:
public interface RemoteVariableBuilder {
public <T> RemoteVariable<T> buildNewVariable(RemoteDeviceProxy wrappedProxy);
}
Then I created non generic sub classes for Boolean...
public class RemoteBooleanVariable extends RemoteVariable<Boolean> implements RemoteVariableBuilder {
public RemoteBooleanVariable(RemoteDeviceProxy wrappedProxy) {
super(wrappedProxy);
}
#SuppressWarnings("unchecked")
#Override
public <T> RemoteVariable<T> buildNewVariable(RemoteDeviceProxy wrappedProxy) {
return (RemoteVariable<T>) new RemoteBooleanVariable(wrappedProxy);
}
#Override
public Boolean get() {
return getWrappedProxy().getBoolean();
}
#Override
public void set(Boolean value) {
getWrappedProxy().setBoolean(value);
}
}
... and Integer ...
public class RemoteIntegerBuilder extends RemoteVariable<Integer> implements RemoteVariableBuilder {
public RemoteIntegerBuilder(RemoteDeviceProxy wrappedProxy) {
super(wrappedProxy);
}
#SuppressWarnings("unchecked")
#Override
public <T> RemoteVariable<T> buildNewVariable(RemoteDeviceProxy wrappedProxy) {
return (RemoteVariable<T>) new RemoteIntegerBuilder(wrappedProxy);
}
#Override
public Integer get() {
return getWrappedProxy().getInteger();
}
#Override
public void set(Integer value) {
getWrappedProxy().setInteger(value);
}
}
actually eclipse created most of the code once it knew base class and interface.
The final step was to create a factory
public class RemoteVariableFactory {
private static final Map<String, RemoteVariableBuilder> BUILDERS = new HashMap<>();
static {
BUILDERS.put(Boolean.class.getName(), new RemoteBooleanVariable(null));
BUILDERS.put(Integer.class.getName(), new RemoteIntegerBuilder(null));
// add more builders here
}
public static <T> RemoteVariable<T> getRemoteVariable(RemoteDeviceProxy wrappedProxy, Class<T> typeClass) {
RemoteVariableBuilder remoteVariableBuilder = BUILDERS.get(typeClass.getName());
if (remoteVariableBuilder == null) {
return null; // or throw an exception whichever is better in your case
}
return remoteVariableBuilder.buildNewVariable(wrappedProxy);
}
}
Now we are ready to create new RemoteVariables...
RemoteVariable<Boolean> var1 = RemoteVariableFactory.getRemoteVariable(new RemoteDevice(), Boolean.class);
RemoteVariable<Integer> var2 = RemoteVariableFactory.getRemoteVariable(new RemoteDevice(), Integer.class);
To conclude this let's do a quick comparison to the answer of Eng.Fouad:
Disadvantage:
you need to create a new class for every datatype you provide
Advantage:
you only have to add one line to the static block of the factory and not two new if blocks to the getter and setter in RemoteVariable
get and set do not have to work through the if-else-blocks every time
I had an interface initially as below.
public interface testMe {
public Set<String> doSomething();
}
public class A implements testMe {
public Set<String> doSomething() {
return // Set<String>
}
}
I had similar classes implementing testMe. Now I have to add one more class which returns Set<Some Object>
public class X implements testMe() {
public Set<Some OBject> doSomething() {
}
}
How could i add this method in the interface without breaking existing classes?
You can use
public interface testMe {
public Set<?> doSomething();
}
Or
public interface testMe {
public Set<? extends CommonSuperclass> doSomething();
}
You can't for two reasons.
A class or interface can't have two or more methods that have the same number and type of parameters with the same name but differing return types; and
Because of type erasure, all Set<...> instances are, at runtime, simply Set, so they would have the exact same return type anyway.
You will need to name the second something different.
The more complicated answer is that you can make the parameter type extensible:
public interface TestMe<T extends Serializable> {
Set<T> doSomething();
}
public class A implements TestMe<String> {
#Override
public Set<String> doSomething() { ... }
}
public class X implements TestMe<ASerializableObject> {
#Override
public Set<ASerializableObject> doSomething() { ... }
}
I don't believe you can, because type erasure will ruin the effect you have in mind.
You can parameterize the interface:
import java.util.Set;
public interface ISomething<T>
{
Set<T> doSomething(T [] data);
}
And the implementation:
import java.util.HashSet;
import java.util.Set;
public class Something<T> implements ISomething<T>
{
public static void main(String[] args)
{
Something<String> something = new Something<String>();
Set<String> set = something.doSomething(args);
System.out.println(set);
}
public Set<T> doSomething(T [] data)
{
Set<T> foo = new HashSet<T>();
for (T x : data)
{
foo.add(x);
}
return foo;
}
}
I'm not sure this accomplishes what you have in mind, though.