For the sample code below...
Is there a way to chain instances of different classes? The example provided is a failed attempt for wiring up methods belonging to different class instances.
Also, In the same example, Client2 is sharing the error object with Client3. What is a more efficient way of sharing objects between subclasses and unassociated classes?
For clarity, i have also commented inline.
Thank You for your time and help.
Sample Code
public class StubRunner
{
public run(){
ClientFactory client = new ClientFactory();
//not correct. But, this is how i want to finally chain methods
//belonging to different class instances. Please advise.
client.getClient1().testClient1().getClient2().testClient2().assert(...);
}
}
public class ClientFactory
{
public Client1 getClient1(){return new Client1();}
public Client2 getClient2(){return new Client2();}
}
public class BaseClient
{
public Errors errors = null;
}
public class Client1 extends BaseClient
{
public void testClient1(){...}
}
public class Client2 extends BaseClient
{
public void testClient2()
{
//here i am directly passing the error object
//what is a better way?
//is there a more efficient way to make the SAME error object
//available to Client3
new Client3(this.errors).testClient3();
...
}
}
public class Client3 extends BaseClient
{
public Client3(Errors errors){this.errors = errors;}
public void testClient3(){...}
}
I would normally use lambda expressions for the cases when I want to program a short chain of method calls but I want the methods to change relatively to any kind of state. As for your scenario, each of your test would be a lambda expression and it would mean that I would pass the testClient4 method to the testClient3 method, the testClient3 method to the testClient2 method, etc. However, the code becomes more and more ugly as your chain of method calls becomes long.
=> You can use Fluent interface: you would have each method doing some logic and then returning an instance on which you can call the next inline methods you want to execute.
ClientFactory.getClient1() : Client1
Client1.testClient1() : Client1 (i.e. return this)
Client1.getClient2() : Client2
Client2.testClient2() Client2 (i.e. return this)
...
Obviously, each instance would need to have a reference to the next inline instance, knowing the one it will call (Client1 would have a reference to Client2, Client2 to Client3, etc).
This would work but I'm not a fan in this scenario! I'd say it's more a trick than clean coding. You should use fluent interface with each client separately unless one of your method is actually returning another instance:
client1.testClient1().testClient2().testClient3()
with each test method returning an instance of the next client if there is a good reason for it
but it wouldn't make sense to interpose the getClient methods between the test methods...
I am not really getting what your need really is, however in the actual state of the code it cannot even compile since you are trying to execute methods from a "Client" object from a void method return.
If you do not know how many clients and from which type you are going to get, I would simply use a list.
If you want to chain the clients using the 'testClient' method, then first this method should return the next client (which is a really awkward way to chain objects by the way), then you should start using more abstraction and overriding technics.
Basically, there's no need to know what object you are dealing with as long as it is a "BaseClient", but if you name the child methods "testClient1", "testClient2" etc ... you basically breaking it and you need to start thinking of what you are actually getting and adapt your code accordingly.
Finally, there's no need for a factory here, but if you want one, it should be static.
Here is a working example of this, again I do not really comprehend what you wanna do so it may not solve your issue, but it's a working solution to "chaining instances":
Main:
public class Foo
{
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
StubRunner stub = new StubRunner();
stub.run();
}
}
Stubrunner:
public class StubRunner implements Runnable
{
public void run(){
Object clients = ClientFactory.getClient1();
while (null!= clients && clients instanceof BaseClient) {
clients = ((BaseClient) clients).test();
}
}
}
Base:
public abstract class BaseClient
{
public Exception errors = null;
public BaseClient() {};
public BaseClient(Exception errors) {
this.errors = errors;
}
public abstract BaseClient test();
public void checkErrors() {
System.out.println(this.toString());
assert null == errors;
}
}
Client 1:
public class Client1 extends BaseClient
{
public BaseClient test(){
checkErrors();
return new Client2();
}
}
Client 2:
public class Client2 extends BaseClient
{
public BaseClient test()
{
checkErrors();
return new Client3(this.errors);
}
}
Client 3:
public class Client3 extends BaseClient
{
public Client3(Exception errors) {
super(errors);
}
public BaseClient test() {
checkErrors();
return null;
}
}
Factory:
public final class ClientFactory
{
private ClientFactory() {};
public static Client1 getClient1(){return new Client1();}
public static Client2 getClient2(){return new Client2();}
}
This outputs the following:
test.Client1#15db9742
test.Client2#6d06d69c
test.Client3#7852e922
Is there a way to chain instances of different classes? The example provided is a failed attempt for wiring up methods belonging to different class instances.
client.getClient1().testClient1().getClient2().testClient2().assert(...);
In order to chain methods like this, each method must return a reference to an object which supports the method which you want to call. However, each test method returns void.
In this case, method chaining seems very questionable because you are operating on different types. Often methods in a chain like this will just return this; so that another method can be called on the exact same object which started the chain.
Additionally, the names of your methods suggest that you are attempting to implement some automated testing of your code. You should learn about established testing techniques and libraries. In particular, JUnit is commonly used in Java and variations in other languages. There are certain techniques that are considered good practice when writing tests in frameworks such as this.
To be clear here, you should certainly not mix testing code with production code.
Also, In the same example, Client2 is sharing the error object with Client3. What is a more efficient way of sharing objects between subclasses and unassociated classes?
//here i am directly passing the error object
//what is a better way?
//is there a more efficient way to make the SAME error object
//available to Client3
new Client3(this.errors).testClient3();
The only way to send an object to a class is to pass a parameter, either to the constructor or to a method. This is how Java works.
Note that there is very little overhead because you are passing a reference variable. You are not copying the entire object. This means that both the current instance of Client2 and the new instance of Client3 have references to the same error object.
Now testClient1() could return the client factory and such. But that is very convoluted.
Another regulatory syntax is to override a context providing class.
new ClientFactory() {{
getClient1().testClient1();
getClient2().testClient2().assert(...);
}};
Here an initializing block ("anonymous constructor") will provide a context.
Then a bit of chaining can be done when testClient2 returns a Client2.
It can be a clean and useful design, for instance for my ambiguous grammar parser AnyParser on sourceforge.net (purely a craftmanship piece of work).
Thank you everyone for the great help. Your advise has allowed me to arrive at the following working solution. Maybe it is not the best, so seeking your valuable time and your expertise to direct to a better solution.
Given some remarks my naming convention being fishy, i have tried to amend them to a certain extent. Kindly bear with me.
Objective was:
To chain instances of different classes
To share objects between subclasses and unassociated classes
Problem description:
There are 4 tasks to be performed: Task1 to Task4.
Each task is unique. But sometimes, to complete a task we need to perform mixed Task: refer Task3 >> performMixedTasks()
To complete a piece of work we need to complete a set of Tasks.
State.java
public class State {
public Boolean ISAUDITED = false;
public int ERRORCODE = 0;
public String ERRORTEXT = "";
public void raise(int code, String msg){
this.ERRORCODE = code;
this.ERRORTEXT = msg;
}
}
BaseClient.java
public abstract class BaseClient {
public State state;
public BaseClient(){
this.state = new State();
}
public BaseClient(State state){
this.state = state;
}
public ClientFactory getTest(){
return new ClientFactory(state);
}
public Boolean Assert(){
if(state.ERRORCODE == 0){
System.out.println("Parsing was successful.");
return true;
}
else{
System.out.println("Parsing was not successful.");
return false;
}
}
public abstract BaseClient GoTo();
}
Task1.java
public class Task1 extends BaseClient {
public Task1(){ GoTo(); }
public Task1(State state){ super(state); GoTo(); }
public Task1 performTask1(){
if(!state.ISAUDITED)
{
System.out.println("perform Task1");
state.ISAUDITED = true;
}
return this;
}
#Override
public BaseClient GoTo() {
if(state.ISAUDITED){
new Task2(state).performTask2();
}
return this;
}
}
Task2.java
public class Task2 extends BaseClient{
public Task2(){ GoTo(); }
public Task2(State state){ super(state); GoTo(); }
public Task2 performTask2(){
if(state.ISAUDITED)
{
System.out.println("perform Task2");
state.ISAUDITED = false;
}
return this;
}
#Override
public BaseClient GoTo() {
if(!state.ISAUDITED){
new Task1().performTask1();
}
return this;
}
}
Task3.java
public class Task3 extends BaseClient {
public Task3(){ }
public Task3(State state){ super(state); }
public Task3 GoTo(){
if(!state.ISAUDITED) {new Task1(state).performTask1();}
System.out.println("Opening Task3");
return this;
}
public Task3 performTask3(){
try
{
this.GoTo();
System.out.println("Submitted Task3 Data");
}
catch(Exception e){
state.raise(1, e.getMessage());
}
return this;
}
public Task3 performMixedTasks(){
new Task4(state).performTask4();
this.performTask3();
return this;
}
}
Task4.java
public class Task4 extends BaseClient {
public Task4(){ }
public Task4(State state){ super(state); }
public Task4 GoTo(){
if(!state.ISAUDITED) {new Task1(state).performTask1();}
System.out.println("Opening Task 4");
return this;
}
public Task4 performTask4(){
try
{
this.GoTo();
System.out.println("Submitted Task 4 Data");
}
catch(Exception e){
state.raise(1, e.getMessage());
}
return this;
}
}
ClientFactory.java
public class ClientFactory {
State state;
public ClientFactory(){
state = new State();
}
public ClientFactory(State state){
this.state = state;
}
public Task3 loadTask3(){return new Task3(state);}
public Task4 loadTask4(){return new Task4(state);}
}
StubRunner1.java
public class StubRunner1 {
public static void main(String[] arg)
{
ClientFactory test = new ClientFactory();
test.loadTask3()
.performTask3()
.getTest()
.loadTask4()
.performTask4()
.Assert();
}
}
**RESULT IS**
perform Task1
Opening Task3
Submitted Task3 Data
Opening Task4
Submitted Task4 Data
Parsing was successful.
StubRunner2.java
public class StubRunner2 {
public static void main(String[] args) {
ClientFactory test = new ClientFactory();
test.loadTask3()
.performMixedTasks()
.Assert();
}
}
**RESULT IS**
perform Task1
Opening Task4
Submitted Task4 Data
Opening Task3
Submitted Task3 Data
Parsing was successful.
Related
I am designing a validation module. It has 100 error codes(i.e. errcd_01, errcd_02,..,errcd_100) to be validated. In input I am getting a specific error code(i.e. errcd_01) out of above 100.
Module should perform validation for that specific error code.
I am using factory pattern.
/* Interface */
public interface validateErrCd {
void check_errcd();
}
/* Concrete classes implementing the same interface */
public class validateErrCd_01 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_01
}
}
public class validateErrCd_02 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_02
}
}
.
.
.
public class validateErrCd_100 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_100
}
}
/* Factory */
public class ErrorValidationFactory {
//use check_errcd method to get object of type shape
public validateErrCd getValidation(String errorCode){
if(errorCode == null){
return null;
}
if(errorCode.equalsIgnoreCase("errcd_01")){
return new validateErrCd_01();
} else if(errorCode.equalsIgnoreCase("errcd_02")){
return new validateErrCd_02();
} ..
.......
else if(errorCode.equalsIgnoreCase("errcd_100")){
return new validateErrCd_100();
}
else {
return null;
}
}
}
/* I am using the Factory to get object of concrete class by passing an specific error code to be validated (i.e. "errcd_01"). */
public class FactoryPatternDemo {
public static void main(String[] args) {
ErrorValidationFactory errorFactory = new ErrorValidationFactory();
//get an object of validateErrCd_01 and call its check_errcd method.
validateErrCd errcd01 = errorFactory.getValidation("errcd_01");
//call check_errcd method of validateErrCd_01
errcd01.check_errcd();
}
}
Now due to multiple if/else inside Factory class ErrorValidationFactory, I am getting couple of CI/CD errors while performing mvn clean install.
e.g. [MethodLength] - checkstyle, Rule:CyclomaticComplexity - PMD.
So is there a way I can replace if/else, switch case kind of decision making inside factory which does not trigger above CI/CD errors in Java?
Note : If possible I would like to avoid reflection
You could use a Map:
public class ErrorValidationFactory {
private Map<String,Supplier<validateErrCd>> creators=new HashMap<>();
public ErrorValidationFactory(){
creators.put("errcd_100",validateErrCd_100::new);
//Same for others
}
//use check_errcd method to get object of type shape
public validateErrCd getValidation(String errorCode){
if(errorCode == null){
return null;
}
return creators.getOrDefault(errorCode,()->null);
}
}
Supplier is a functional interface that contains a method returning an object. SomeClass::new or ()->new SomeClass() means that the constructor of the class will be used for that.
This allows to to create the instances later.
If you want to create the Map only once, you can make it static and populate it in a static initializer.
However, if you really want to dynamically get the constructors, you would need to use reflection.
I have class three classes. Pref, ClassA, and ClassB.
public class Pref{
public static ArrayList<Pref> prefList;
public static Observable<ArrayList<Pref>> observable;
public static void loadData(){
prefList = getFromDb();
observable = Observable.just(prefList);
}
}
Application runs the ClassA First.
public ClassA{
public ClassA(){
initObserver();
setObserver();
}
public void initObserver(){
Pref.loadData();
}
public void setObserver(){
Observer<ArrayList<Pref>> obs = new Observer() {
#Override
public void onSubscribe(Disposable dspsbl) {
System.out.println("Subscribed");
}
#Override
public void onNext(ArrayList<Pref>> t) {
System.out.println("Loading Preference.");
//Need to do some other works here.
}
#Override
public void onError(Throwable thrwbl) {
}
#Override
public void onComplete() {
}
};
Pref.observable.subscribe(obs);
}
}
Now I want to change the list from ClassB.
public class ClassB{
private void changeList(){
Pref.prefList = loadDataFromSomeSource();
}
}
When I run ClassA, the System.out works fine. But when I change the list from ClassB nothing happens. My question is, is the right way to work with Rxjava. Is it for Rxjava built? If I am wrong how can I achieve this functionality? How can I write several ClassA like classes so that When the ClassB::changeList() runs, I can listen it in ClassA?
By setting Pref.prefList = loadDataFromSomeSource();, you assign a new list instance to Pref.prefList. This will not update Pref.observable in any way, because this still refers to the old Pref.prefList instance.
I also think that you can not use an Observable to publish events through it. As far as I understand your situation, you need an ObservableSource (see http://reactivex.io/RxJava/javadoc/io/reactivex/ObservableSource.html). For example, it is implemented by PublishSubject. You could use it like this:
PublishSubject<String> source = PublishSubject.create();
source.subscribe(System.out::println);
source.onNext("test 1");
source.onNext("test 2");
source.onNext("test 3");
Or, in your case: in class Pref, you can use public static PublishSubject<ArrayList<Pref>> source = PublishSubject.create();. When loading the data, you can publish the new data using onNext, like this in ClassB: Pref.source.onNext(loadDataFromSomeSource())
Imagine I have the following class structures:
public interface Sender {
void send(String note);
}
public interface Agent {
void sendNote(String note);
}
public class Emailer implements Sender {
void send(String note) {
//...do something
}
}
public class Helper {
List<String> populateNotes() {
//...do something
}
}
public class EmailAgent implements Agent {
List<String> notes;
void sendNote(String note) {
Helper helper = new Helper();
notes = helper.populateNotes();
for (String s : notes) {
Sender sender = new Emailer();
sender.send(s);
}
}
}
Now, I want to unit test the sendNote() method in EmailAgent. However, there is a dependency on Helper as it needs to populate the list notes. If in the JUnit test I first call populateNotes() before calling sendNote()...
Is this a unit test or acceptance test?
Or should I hard coded the list?
Or use suggestion 2 - create a stub producing a hard-coded list - then unit test the sendNote method. Mocking would also help with this but requires coding against interfaces to be of any use. While it will work, a simple stub should also do the trick.
I am trying to use RabbitMQ and based on different message, different implements should be called.
I set the message format as of JSON, and there is a field "callType", the value of it is the class name implements a common interface. e.g, all implementations have implements interface "Task", and I have implementation of "TaskImp1","TaskImp2","TaskImp3".
So the code should be like
if (callType=="TaskImp1")
((Task)TaskImp1).runTask()
if (callType=="TaskImp2")
((Task)TaskImp2).runTask()
if (callType=="TaskImp3")
((Task)TaskImp3).runTask()
But could it be more flexible? If later I develop a new one "TaskImp4", I don't want to change the calling code, is it possible to have java automatically pick the right implementation since the callType is actually the class name of the implementation.
Yes, for example, through Java reflection (What is reflection and why is it useful?). Reflection has a performance cost though (Java Reflection Performance)
Sure: put your Task instances in a map:
private Map<String, Task> tasksByName = new HashMap<>();
...
tasksByName.put("TaskImp1", new TaskImp1());
tasksByName.put("TaskImp2", new TaskImp2());
tasksByName.put("TaskImp3", new TaskImp3());
...
String callType = message.getCallType();
Task task = tasksByName.get(callType);
task.runTask();
Also, read How do I compare strings in Java?
You have an opportunity to use Strategy here. So for e.g. you could do like:
public class MyTask {
private Task task;
public MyTask(Task task) {
this.task = task;
}
public void doSomething() {
task.runTask();
}
public static void main(String args[]) {
MyTask task = new MyTask(new TaskImpl1());//or even you could use setTask() api to inject task at runtime rather than doing cast on compile time.
task.doSomething();
task = new MyTask(new TaskImpl2());
task.doSomething();
task = new MyTask(new TaskImpl3());
task.doSomething();
}
}
In this way you could make your code extensible. Tomorrow if you have taskImpl4, you could code it independently and inject in MyTask without even touching MyTask class implementation.
As #ovdsrn already said you can use reflection. Simple example would be something like (the key is getTask static method. Also, note that, when you are using Class.forName you must specify whole "path" (package) for your class)
// ITask.java
package main;
public interface ITask {
void doSomething();
}
// Task1.java
package main;
public class Task1 implements ITask {
#Override
public void doSomething() {
System.out.println("Task1");
}
}
// Task2.java
package main;
public class Task2 implements ITask {
#Override
public void doSomething() {
System.out.println("Task2");
}
}
// main
package main;
public class JavaTest {
private static ITask getTask(String name) {
try {
Class<?> cls = Class.forName(name);
Object clsInstance = (Object) cls.newInstance();
return (ITask)clsInstance;
} catch (Exception e) { // you can handle here only specific exceptions
return null;
}
}
public static void main(String[] args) {
String name = args.length > 0 ? args[0] : "Task2";
ITask task = getTask("main." + name);
if (task != null) {
task.doSomething();
}
else {
System.out.println("can not make instance of class: " + name);
}
}
}
I'm working on a game engine, and the last question I had regarding this was what good way I can use to make "observers" or listeners. A user suggested that I should use Java's EventObject class to inherit from and make a Listener interface. However, this didn't provide me with good flexibility.
Here is the Handler annotation to state that a method is an event handler in a listener:
#Retention(RetentionPolicy.CLASS)
#Target(ElementType.METHOD)
public #interface Handler {}
Here is the base class for Event, which is basically the same as EventObject (but I'll add abstract methods sooner or later):
public abstract class Event {
private Object source;
public Event(Object source) {
this.source = source;
}
public Object getSource() {
return source;
}
}
Here is the Listener class, which is empty:
public interface Listener {}
Here is the ListenerHandler class, used to handle all listeners. You register and unregister them here. I'll edit the register/unregister methods later for a better use:
public class ListenerHandler {
private ArrayList<Listener> listeners;
public ListenerHandler() {
this.listeners = new ArrayList<Listener>();
}
public void registerListener(Listener l) {
listeners.add(l);
}
public void unregisterListener(Listener l) {
listeners.remove(l);
}
public void onEvent(Event event) {
for(Listener l : listeners) {
Class<?> c = l.getClass();
Method[] methods = c.getDeclaredMethods();
for(Method m : methods) {
if(m.isAccessible()) {
if(m.isAnnotationPresent(Handler.class)) {
Class<?>[] params = m.getParameterTypes();
if(params.length > 1) {
continue;
}
Class<?> par = params[0];
if(par.getSuperclass().equals(Event.class)) {
try {
m.invoke(this, event);
}catch(IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
}
}
}
From what I heard, it's a use of a lot of memory in order to get all methods of a class. I'm not going to assume this is the case, but I'm sure there is a better way as this will be a game engine with many components and such.
I'd like to know the best way to implement this, or if I'm doing it right. I'd also like to know if anyone can help me improve this in any way without hogging memory usage by the game (as of now it's not a big deal -- the "game engine" is not even close to rendering anything yet)
I tried to keep it a very simple example and will comment with different ideas to it:
First meet the Achievement class:
import java.util.Observable;
public class Achievement extends Observable {
public static class AchievementDetails {}
public Achievement() {
addObserver(EventsListener.getInstance());
}
public void achievementReached() {
AchievementDetails achievemetDetails = null;
setChanged();
notifyObservers(achievemetDetails);
}
}
And then the events listener class:
import com.test.Achievement.AchievementDetails;
public class EventsListener implements Observer {
private static EventsListener instance = new EventsListener();
public static EventsListener getInstance() {
return instance;
}
#Override
public void update(Observable o, Object arg) {
if(o instanceof Achievement) {
AchievementDetails achievemetDetails = (AchievementDetails) arg;
//do some logic here
}
}
}
The only one thing that is missing is to create an instance of your achievement (which register the EventsListener to itself) and handle the life cycle of it.