I have multiple services that implement interface with one method - execute(). Each service uses this method to execute some actions based on a String value, which, in original code, is enum, so those values are constants.
interface Service{
public void execute();
}
class Service1 implements Service{
//constructors
public void execute(JSONObject payload, String payloadType){
if(payloadType.equals("type1")){
doSomething(payload);
}
}
}
class Service2 implements Service{
//constructors
public void execute(JSONObject payload, String payloadType){
if(payloadType.equals("type1")){
doSomething1(payload);
}
if(payloadType.equals("type2")){
doSomething2(payload);
}
}
}
I want to avoid writing same if statements each time I create a new Service. Problem is, that each Service doesn't have to execute actions based on each string types. So Service1 executes action when type is equal to "type1", however Service2 executes actions based on "type1" and "type2".
I tried following solution:
class Main {
public static void main(String[] args) {
exec(new B(), "type2");
}
private static void exec(Service service, JSONObject payload, String payloadType){
if(payloadType.equals("type1")){
Init i = (Init)service;
i.init(payload);
}
if(payloadType.equals("type2")){
Action a = (Action)service;
a.action(payload);
}
}
}
interface Service{
}
interface Init{
public void init(JSONObject payload);
}
interface Action{
public void action(JSONObject payload);
}
class A implements Service, Init{
#Override
public void init(JSONObject payload){
doSomething(payload);
}
}
class B implements Service, Init, Action{
#Override
public void init(JSONObject payload){
doSomething1(payload);
}
#Override
public void action(JSONObject payload){
doSomething2(payload);
}
}
The above code works, but I don't like using casting. I think it's not a good practice, also very unsafe. Could you suggest, what design pattern or other solution could I use here? I tried visitor, but I couldn't figure out the right implementation with this case.
UPDATE
Thanks for all the answers, they were very helpfull. I managed to achieve what I was looking for. Here's the code that finally works.
public class Main {
public static B b = new B();
public static A a = new A();
public static void main(String[] args) {
exec(b, "init");
}
private static void exec(Service service, String type){
if(type.equals("init") && service instanceof Init){
service.fillCarrier(new InitCarrier());
}
if(type.equals("action") && service instanceof Action){
service.fillCarrier(new ActionCarrier());
}
}
}
interface Carrier<T>{
public void set(T t);
}
class InitCarrier implements Carrier<Init>{
public void set(Init init){
init.init();
}
}
class ActionCarrier implements Carrier<Action>{
public void set(Action action){
action.action();
}
}
abstract class Service{
public void fillCarrier(Carrier carrier){
carrier.set(this);
}
}
interface Init{
public void init();
}
interface Action {
public void action();
}
class A extends Service implements Init{
#Override
public void init(){
System.out.println("init a");
}
}
class B extends Service implements Init, Action{
#Override
public void init() {
System.out.println("init b");
}
#Override
public void action(){
System.out.println("action");
}
}
To achieve this requirement, we need to pattern.
Factory pattern.
Strategy pattern.
TypeFactory creates an object based on the string we delivered. Each Type implementation implements a doSomething() method in its own way. (factory pattern is used here)
Type Strategy:
interface Type{
public void doSomething();
}
class TypeOne implements Type{
#Override
public void doSomething() {
System.out.println("Type One!");
}
}
class TypeTwo implements Type{
#Override
public void doSomething() {
System.out.println("Type Two!");
}
}
Type Factory:
class TypeFactory{
Type type;
public Type createType(String condition) {
if (condition == null || condition.isEmpty()) {
return null;
}
if ("type1".equals(condition)) {
return new TypeOne();
}
else if ("type2".equals(condition)) {
return new TypeTwo();
}
return null;
}
}
Now to achieve the final goal, we need to declare a Service interface with an execute method. This execute method takes Type as an input parameter. Based on which type you actually pass, the corresponding doSometing method will be invoked. (strategy pattern used only)
interface Service{
public void execute(Type type);
}
class ServiceOne implements Service{
#Override
public void execute(Type type) {
System.out.print("Service One - ");
type.doSomething();
}
}
class ServiceTwo implements Service{
#Override
public void execute(Type type) {
System.out.print("Service Two - ");
type.doSomething();
}
}
Main Class looks like this:
public class DesignPatternCombo {
public static void main(String[] args) {
Type typeOne = new TypeFactory().createType("type1");
Type typeTwo = new TypeFactory().createType("type2");
Service serviceOne = new ServiceOne();
serviceOne.execute(typeOne);
Service serviceTwo = new ServiceTwo();
serviceTwo.execute(typeOne);
serviceTwo.execute(typeTwo);
}
}
Expected output:
Service One - Type One!
Service Two - Type One!
Service Two - Type Two!
Tricky question, I may have a solution that could work.
That would be to store the Types, with the code that type does in the form of a HashMap.
HashMap<String, Function<Void, Void>> types = new HashMap<String, Function<Void, Void>>();
Then in the main function, you would fill up the HashMap with the names of the types, and the function it runs.
types.put("Type1",()->{
/*Do something*/
});
types.put("Type2",()->{
/*Do something*/
});
types.put("Type3",()->{
/*Do something*/
});
Then in the Service, you would have an array of Strings for what types it uses. Such as:
String[] serviceTypes = {"Type1", "Type2"};
Finally, in the execute function of the Service you would run the corresponding lambda to the string.
public void execute(String type){
if((new ArrayList<>(Arrays.asList(serviceTypes))).contains(type)) {
Main.types.get(type);
}
}
You might work with an abstract base class.
The base class implements Service and has the execute() method. It does not get around if statements, but after all it could have a list of allowed values, and as soon as the type parameter is contained in the list it would call another method. Per default the method does nothing.
Concise subclasses of the base no longer need to perform the if conditions as they simply override the single methods in the base class. So this works for a whole bunch of quite similar services.
The advantage of this approach is if you have some exotic, incompatible type of service you can skip the if statements by directly overwriting the execute() method. So that pattern is extensible, which is probably worth more than saving a few more if statements.
You can solve this elegantly with the Strategy Design Pattern.
Create a common interface called Strategy
interface Strategy {
void execute(JSONObject payload);
}
Create multiple implementations of Strategy according to your needs:
class ServiceType1 implements Strategy {
//constructors and fields
#Override
public void execute(JSONObject payload) {
//code to be executed for "type1"
}
}
class ServiceType2 implements Strategy {
//constructors and fields
#Override
public void execute(JSONObject payload) {
//code to be executed for "type2"
}
}
...
Group the Service implementations by type, eg.:
Map<String, Strategy> strategyMap = new HashMap<>();
strategyMap.put("type1", new ServiceType1());
strategyMap.put("type2", new ServiceType2());
...
Invoke the desired Service without the need for any if statements, like this:
private static void exec(String payloadType, JSONObject payload) {
strategyMap.get(payloadType).execute(payload);
}
P.S.: if all implementations of Strategy share some common behaviour, you can convert Strategy from interface to abstract class and move the common behaviour there.
wow, your architecture seems much complex. you should consider better hierarchy. but if you can't, why don't you just make a method on Service and let the subtype decide what behavior they want. Then you can call that method from Service to execute
static class Main {
public static void main(String[] args) {
exec(new B());
}
private static void exec(Service service){
service.execute();
}
}
interface Service{
void execute();
}
interface Init{
public void init();
}
interface Action{
public void action();
}
static class A implements Service, Init{
#Override
public void init(){
System.out.println("init a");
}
#Override
public void execute(){
init();
}
}
static class B implements Service, Init, Action{
#Override
public void init(){
System.out.println("init b");
}
#Override
public void action(){
System.out.println("action");
}
#Override
public void execute(){
action();
}
}
What about extracting common logic to the separate class. It cloud be:
BaseService and all other services should implement this one;
ServiceDelegate and all other services should delegate all work to this one.
The below snippet provides the first solution.
// This is you Service interface
public interface Service {
void execute(JSONObject payload, String payloadType);
}
// This is base implementation. Use `Map` to replace `if` statements
public abstract class BaseService implements Service {
private static final Consumer<JSONObject> NULL = jsonObject -> { };
private final Map<String, Consumer<JSONObject>> consumers;
protected BaseService(Map<String, Consumer<JSONObject>> consumers) {
this.consumers = consumers == null || consumers.isEmpty() ? Map.of()
: Collections.unmodifiableMap(consumers);
}
#Override
public final void execute(JSONObject payload, String payloadType) {
consumers.getOrDefault(payloadType, NULL).accept(payload);
}
}
public class ConcreteService extends BaseService {
private static final Consumer<JSONObject> DO_SOMETHING_TYPE1 = jsonObject -> {
// TODO implementation for "type1"
};
private static final Consumer<JSONObject> DO_SOMETHING_TYPE2 = jsonObject -> {
// TODO implementation for "type2"
};
public ConcreteService() {
super(Map.of(
"type1", DO_SOMETHING_TYPE1,
"type2", DO_SOMETHING_TYPE2));
}
}
I'm trying to use interfaces in my android java project. Callback interfaces seems to be the answer to C# delegates, but I can't get my head around it, I've read other similar questions, but again, I can't get it to fit my needs or get it to work. What I need is to call a function in Class A that is pass as a parameter to Class B. When class B finishes a task, returns the result to A by calling the function previously saved in a variable:
class A {
B myBClass;
public A() {
myBClass = new B();
myBClass.doSomething(ResultFunction);
//Continue doing other tasks
}
public void ResultFunction(<result parameters>) {
//do something with the result from the task in myBClass
}
}
class B {
Function myCallback;
public B() {
}
public void doSomething(ResultFunction) {
myCallback = callback;
//does something
SomethingFinished();
}
private void SomethingFinished() {
myCallback.call(<result of doSomething>);
}
}
There are 2 ways to do it:
1) Use anonymous class:
Remove ResultFunction argument from doSomething method in class B
And reimplement it in class A
public A() {
myBClass = new B() {
#Override
public void doSomething() {
super.doSomething();
//do here what you need what you want to do in B class
}
}
myBClass.doSomething();
//Continue doing other tasks
}
2) UseCallable interface
interface Callable {
public void call();
}
pass it instead of ResultFunction
class A {
B myBClass;
Callable callable = new Callable {
#Override
public void call() {
//do here what you need what you want to do in B class
}
}
public A() {
myBClass = new B();
myBClass.doSomething(callable);
//Continue doing other tasks
}
}
class B {
Callable myCallback;
public B() {
}
public void doSomething(Callable callable) {
myCallback = callable;
//does something
SomethingFinished();
}
private void SomethingFinished() {
myCallback.call();
}
}
With lambdas it can look like a bit better
public A() {
myBClass = new B();
myBClass.doSomething(()->{
//do here what you need what you want to do in B class
});
//Continue doing other tasks
}
I do not understand why can't you just do the following:
public class A {
private B myBClass;
public A() {
myBClass = new B();
Result result = myBClass.doSomething();
resultFunction(result)
//Continue doing other tasks
}
public void resultFunction(Result result) {
//do something with the result from the task in myBClass
}
}
public class B {
public B() {
}
public Result doSomething() {
//does something
}
}
If, for whatever reason, you must do that, you can do it easily in Java 8 like this:
public class A {
B myBClass;
public A() {
myBClass = new B();
myBClass.doSomething(A::resultFunction);
//Continue doing other tasks
}
public void resultFunction(Result result) {
//do something with the result from the task in myBClass
}
}
public class B {
private Consumer<Result> myCallback;
public B() {
}
public void doSomething(Consumer<Result> callback) {
myCallback = callback;
//does something
myCallback.accept(result);
}
}
I have following situation and would like to know the best way to design my solution
public abstract class A {
public abstract A getHelper();
public abstract void launchHandle();
public static A initHelper(String condition) throws Exception {
if ( condition == 'xyz') {
return C.getHelper();
} else {
return B.getHelper();
}
}
}
public class B extends A {
protected static A b;
#Override
public A getHelper() {
b = new B();
return b;
}
#Override
public void launchHandle() {
System.out.println("Launching Handle");
}
public String getName() {
return "I am from Class B";
}
}
public class C extends A {
protected static A c;
#Override
public A getHelper() {
c = new C();
return c;
}
#Override
public void launchHandle() {
System.out.println("Launching Handle from C");
}
public String getValue() {
return "I am from Class C";
}
}
**Executor class**
public class Executor {
public static void main(String[] args) {
A aa = a.initHelper(condition);
}
}
Now in the above approach, i am unable to access methods like aa.getName() from Class B OR aa.getValue() from Class C, which makes sense. However how to get these methods in executor class? Executor does not know anything about Class B & C and should not know. Executor is only aware of Class A, but want to access methods SubClass methods from B & C which are extended from Class A.
Please help design this and what could be best way to solve this.
Thanks in advance.
Executor is only aware of Class A, but want to access methods SubClass methods from B & C which are extended from Class A.
If you take a closer look at your code, you will notice that the only contract constant across all your classes is the launchHandle method (baring getHelper and initHelper which are simply used for instantiating the right subclass). There is no real relation between B and C other than the fact that their instantiation is controlled by A.
This is how I would consider approaching the problem :
Executor Factory
Make Executor an abstract class rather than making it the entry point of your program :
public abstract class Executor {
public abstract void performTask();
public static void execute(String condition) {
Executor executor = null;
if ( condition.equals("xyz")) {
executor = new AExector();
} else {
executor = new BExecutor();
}
executor.performTask();
}
}
Executor implementations
Create a different implementation for operating on B called BExecutor :
public class BExecutor extends Executor {
public void performTask() {
System.out.println("launching handle from B");
//create or get data to perform the task on
B b = new B();
String name = b.getName();
System.out.println("I am from "+name);
}
}
Create a different implementation for operating on C called CExecutor :
public class CExecutor extends Executor {
public void performTask() {
System.out.println("launching handle from C");
//create or get data to perform the task on
C c = new C();
String value = c.getValue();
System.out.println("I am from "+value);
}
}
Your main method can then look like this :
public static void main(String []args) {
Executor executor = Executor.execute(condition);
}
And for some reason, if you do find some common contract between B and C, you an always create an interface which both B and C can implement and use a reference of this interface instead of using a B or C reference.
Add getName and getValue to A as abstract methods.
I want advice on what should I do:
I have a class A and B such that
public class A {
int result;
int a;
public A(){
result =0;
a = 5;
B myB= new B();
System.out.println(result);
}
public void main(){
A myA= new A();
}
}
public class B extends Thread {
public B(){
start();
}
public void run() {
addition1();
}
public void addition1() {
////////HERE trying to do///////
result = a+5;
}
}
Unfortunally, I need to use, peferable two classes and must two threads and the addition will be perform in the second thread and update the first thread.
This is just an example I came that shows what my issues are. my real code was far too long to post in here.
Thanks
I assume that when you say that you want to update from one thread to another you should have had Class A also as an extension of Thread or a Runnable object. However Class A in your example is not a Thread extension and can be updated by an operation in B (which is another thread) in a usual way like you can update a shared variable in multi threaded scenario. Just expose a setter method for the result variable in Class A and update it from the B class method (addition1) which is running in new thread. Therefore you would have updated a shared instance (of class A) being operated upon by main thread (the first thread) from another thread (spawned during construction of Class B) method (addition1)
You can try with Callback Mechanism to get the result back one it's computed.
For more info read inline comments.
Sample code:
interface Callback {
public void execute(int result);
}
// make it abstract and don't provide implementation of execute method here
abstract class B extends Thread implements Callback {
private A a;
// pass the reference of Class A to access it
public B(A a) {
this.a = a;
start();
}
public void run() {
addition1();
}
public void addition1() {
int result = a.a + 5;
//result is computed now call pass the value to the waiter and that's A
execute(result);
}
}
class A {
int result;
int a;
public A() {
result = 0;
a = 5;
B myB = new B(this) {// pass the reference of Class A
#Override
public void execute(int result) {
// This is the computed result that is returned from Class B
System.out.println(result);
}
};
}
}
Consider following SWT code example:
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet151.java?view=co
How can I separate the inline defined class?
Thread thread = new Thread() {
public void run() {
...
}
};
I want to define a separate class which updates the table just like it does here. How do I pass the list back to the table? Example code?
Just create a class which extends Thread.
public class Task extends Thread {
public void run() {
// ...
}
}
and create it as follows:
Task task = new Task();
The normal practice is however to implement Runnable:
public class Task implements Runnable {
public void run() {
// ...
}
}
Or if you want a Thread which returns a result, implement Callable<T> where T represents the return type.
public class Task implements Callable<String> {
public String call() {
// ...
return "string";
}
}
Both can be executed using the ExecutorService.
I would not create a class that extends Thread. It's more likely that you'll have a class that implements Runnable and provides access to private data members:
public class YourTask implements Runnable
{
private ResultClass result;
public void run() { }
public ResultClass getResult() { return result; }
}
Have a look at java.util.concurrent packages and the new FutureTask. I think that's a better bet.
You can work passing parameters or setting globally visible attributes, example:
class Foo
{
public static String baz = "baz";
private String bar = "bar";
void startThread()
{
MyThread thread = new MyThread(bar);
thread.start();
}
}
class MyThread extends Thread
{
String ref;
MyThread(String ref)
{
this.ref = ref;
}
public void run()
{
// it can work with passed parameter
System.out.println(ref);
// but also with globally visible variables
System.out.println(Foo.baz);
}
}