how the instanceof usage can be avoided? - java

How can we avoid using instanceof operator for writing a clean code
say for example:
If an object is of Type1 do something, but if it is of Type2 then do something else.
if(obj instanceof T1){
doSomething()
}else(obj instanceof T2){
doOtherThing()
}

Generally you use a series of instanceof with a cast to invoke a specific method that exists in a class but not in others :
if(obj instanceof T1){
((T1)obj) doSomething();
}
else(obj instanceof T2){
((T2)obj) doOtherThing();
}
To avoid that, if you can modify these classes, T1 and T2 should be subclasses of a common base class and the invoked method should be defined in the base class.
In this way, each subclass may implement it and you could so write :
obj.doSomething();
if you cannot modify these classes, you can always introduce an Adapter class that wraps them to provide a common way to invoke these methods.
Adapter
public interface Adapter{
void process();
}
AdapterForT1
public class AdapterForT1 implements MyAdapter{
private T1 adapted;
public AdapterForT1(T1 adapted){
this.adapted = adapted;
}
public void process(){
adapted.doSomething();
}
}
AdapterForT2
public class AdapterForT2 implements MyAdapter{
private T2 adapted;
public AdapterForT2(T2 adapted){
this.adapted = adapted;
}
public void process(){
adapted.doOtherThing();
}
}
And you may use them in this way :
MyAdapter adapter = new AdapterForT1(obj);
...
adapter.process();
or :
MyAdapter adapter = new AdapterForT2(obj);
...
adapter.process();

You need to use method overriding here and then call the same function from different instances of different classes which will execute a different set of instructions as per implemented in individual classes
So for instance, you have a class T and then class T1 and class T2 both extends class T and all three classes implement executeTask function
So,
T t1 = new T1();
T t2 = new T2();
// this will execute function overridden in T1
t1.executeTask();
// this will execute function overridden in T2
t2.executeTask();

Create an interface, which both classes implement. An interface is sort of a contract that every implementing class has to comply with.
With this you can ensure that every instance of such a class has all defined methods from that interface implemented.
For example:
public interface CustomExecutable {
void execute();
}
Then your two classes:
public class T1 implements CustomExecutable {
#Override
public void execute() {
// Do t1 logic
}
}
public class T2 implements CustomExecutable {
#Override
public void execute() {
// Do t2 logic
}
}
In your main program you could do something like this:
CustomExecutable ce = new T1();
ce.execute(); // Does t1 logic
ce = new T2();
ce.execute(); // Does t2 logic
instanceof isn't necessary anymore, because each type has its own way of executeing its code.

Related

Thread-safe inheritance

I create a hierarchy from an abstract class and two children that are used in class F and pass them to the service
#Getter
abstract class A {
private final B b;
public A(B b) {
this.b = b;
}
abstract void doSomething();
}
#Getter
class B {
private final String someProperty;
}
class C extends A {
public C(B b) {
super(b);
}
#Override
void doSomething() {
super.getb().getSomeProperty();
}
}
class D extends A {
public D(B b) {
super(b);
}
#Override
void doSomething() {
super.getb().getSomeProperty();
}
}
#RestController
class F {
#Autowired
private Service service;
#GetMapping
public void methodOne() {
A a1 = new C(new B("ccc"));
service.make(a1);
}
#GetMapping
public void methodTwo() {
A a1 = new D(new B("ddd"));
service.make(a1);
}
}
#Service
public class Service {
public void make(A a) {
a.doSomething();
}
}
The construction that I described above in case we have a lot of clients who call our API will there be any problems in thread safety with the state of our abstract class or not?
"Thread Safety" thing comes into the picture when multiple threads are trying to manipulate same object and by allowing to do so may end up with inconsistent state of the Object which is obviously not acceptable for any application.
Your question is about the Object you've declared in your abstract parent class, now as I said earlier the problem will only be there if multiple threads are using the same object, since you're creating new objects every time the service method is getting called, you are safe why?, because the scope of the object is limited to the method and multiple threads can not use the same object as for each method call you'll have a different object.
Now consider this case, in this case thread safety is a concern,
#Service
class UnSafeClass {
private MyClass myClassObject;
public void doSomething() {
myClassObject.changeData();//Same object will be used by multiple threads
}
}
So, your current implementation does not have any thread safety concerns but we should definitely need to clarify on where exactly you need to take care of thread safety.

Is this an anti-pattern or violates it some design-principles?

I try myself with design-patterns & -principles and have a question.
Before, sorry for the bad coding-style habit !!
I have an interface like ITest in this case:
public interface ITest
{
public void method1();
}
and then implement the methods and fields, if any, into a concrete class B like this:
public class B implements ITest
{
//This is the method from the interface
#Override
public void method1()
{
System.out.println("method1");
}
//This is another method in class B
public void method2()
{
System.out.println("method2");
}
}
Now in the application code I put it in like this:
public class Main
{
public static void main(final String args[]) throws Exception
{
//One principle says:
//programm to an interface instead to an implementation
ITest test = new B();
//method from interface
test.method1();
//this method is not accessible because not part of ITest
test.method2(); //compile-time error
}
}
You see that method2() from class B is not available because to the interface of ITest.
Now, what if I need this 'important' method?
There are several possibilities. I could abstract it in the interface or make class B abstract and extend into another class and so on, or make the reference in the main() method like:
B test = new B();
But this would violate the principle.
So, I modified the interface to:
public interface ITest
{
//A method to return the class-type B
public B hook();
public void method1();
}
And put in class B the implementation:
public class B implements ITest
{
//this returns the object reference of itself
#Override
public B hook()
{
return this;
}
//This is the method from the interface
#Override
public void method1()
{
System.out.println("method1");
}
//This is the 'important' method in class B
public void method2()
{
System.out.println("method2");
}
}
Now in my main()-method I can call both methods with a little hook or chaining mechanism without referencing a new object nor does it violate the design-principle and I don't need an extra class for extension or abstraction.
public class Main
{
public static void main(final String args[])
{
//programm to an interface instead into an implemintation
ITest test = new B();
//method from interface
test.method1();
//method2 will not be accessible from ITest so we referencing B through a method hook()
//benefits: we don't need to create extra objects nor additional classes but only referencing
test.hook().method2();
System.out.println("Are they both equal: "+test.equals(test.hook()));
}
}
Also, I can encapsulate, inherit and abstract other methods, fields etc.
This means, that I can create more complex and flexible hierarchies.
My question now:
Is this a kind of anti-pattern, bad design-principle or could we benefit from this?
Thank you for watching. :-)
Is this a kind of anti-pattern, bad design-principle or could we
benefit from this?
Yes, it is a bad pattern.
The problem stems from the fact that you have tightly coupled ITest to B. Say I want to create a new implementation of ITest - let's call it C.
public class C implements ITest
{
#Override
public B hook()
{
// How do I implement this?
}
#Override
public void method1()
{
System.out.println("method1");
}
}
There's no sane way we can implement this method. The only reasonable thing to do is to return null. Doing so would force any users of our interface to constantly perform defensive null checks.
If they're going to have to check every time before using the result of the method, they might as well just do an instanceof and cast to B. So what value are you adding? You're just making the interface less coherent and more confusing.
Adding a method returning B to interface ITest implemented by B is definitely an awful design choice, because it forces other classes implementing ITest return B, for example
public class C implements ITest {
#Override
public B hook()
{
return // What do I return here? C is not a B
}
...
}
Your first choice is better:
B test1 = new B();
C test2 = new C();

How to share a variable between two sub classes that implements runnable

I have a main class and two subclasses, subClass1 and subClass2 that implements runnable...
I have run the two threads simultaneously
by calling
t1.start // t1 for subclass1
t2.start // t2 for subclass2
Now, I want t1 to run till the t2 completes.
I can add a boolean flag within the method in subclass2 to recognize that the execution has been completed;
Now I need to pass that information(boolean variable) to subclass1 to stop the execution of a set of codes from within it. [have used while(true) loop;]
so how can i create a common variable that can be accessed by both sub classes?
Can anybody please suggest me a solution for this?
Pass an AtomicBoolean to the subclasses.
public class SubClass1 implements Runnable {
private AtomicBoolean b;
public SubClass1(AtomicBoolean b) {
this.b = b;
}
public void run() {
while(b.get()) { // Assuming SubClass2 sets it to false when it's no longer running
// Do something
}
}
}
Implementing SubClass2 is left as an exercise to the OP.
If possible I'd recommend to avoid sharing mutable state in concurrent environment, but assuming you have one of those cases where it cannot be avoided you can try something like (adjust for your own needs):
class SharedState {
public final Object mutex = new Object();
public boolean variable;
}
class Subclass extends MyClass1 implements Runnable {
private SharedState sharedState;
public Subclass1(SharedState sharedState) {
this.sharedState = sharedState;
}
// ...
#Override
public void run() {
// ...
synchronized(sharedState.mutex) {
// access sharedState.variable
}
// ...
}
}
Basically create SharedState outside and inject into your subclasses on creation (or create it within one of them, retrieve and inject into another, whatever). Then use that shared variable remembering all you know about trickiness of shared state.

Calling methods from objects which implement an interface

I am trying to wrap my head around interfaces, and I was hoping they were the answer to my question.
I have made plugins and mods for different games, and sometimes classes have onUpdate or onTick or other methods that are overridable.
If I make an interface with a method, and I make other classes which implement the method, and I make instances of the classes, then how can I call that method from all the objects at once?
You'll be looking at the Observer pattern or something similar. The gist of it is this: somewhere you have to keep a list (ArrayList suffices) of type "your interface". Each time a new object is created, add it to this list. Afterwards you can perform a loop on the list and call the method on every object in it.
I'll edit in a moment with a code example.
public interface IMyInterface {
void DoSomething();
}
public class MyClass : IMyInterface {
public void DoSomething() {
Console.WriteLine("I'm inside MyClass");
}
}
public class AnotherClass : IMyInterface {
public void DoSomething() {
Console.WriteLine("I'm inside AnotherClass");
}
}
public class StartUp {
private ICollection<IMyInterface> _interfaces = new Collection<IMyInterface>();
private static void Main(string[] args) {
new StartUp();
}
public StartUp() {
AddToWatchlist(new AnotherClass());
AddToWatchlist(new MyClass());
AddToWatchlist(new MyClass());
AddToWatchlist(new AnotherClass());
Notify();
Console.ReadKey();
}
private void AddToWatchlist(IMyInterface obj) {
_interfaces.Add(obj);
}
private void Notify() {
foreach (var myInterface in _interfaces) {
myInterface.DoSomething();
}
}
}
Output:
I'm inside AnotherClass
I'm inside MyClass
I'm inside MyClass
I'm inside AnotherClass
Edit: I just realized you tagged it as Java. This is written in C#, but there is no real difference other than the use of ArrayList instead of Collection.
An interface defines a service contract. In simple terms, it defines what can you do with a class.
For example, let's use a simple interface called ICount. It defines a count method, so every class implementing it will have to provide an implementation.
public interface ICount {
public int count();
}
Any class implementing ICount, should override the method and give it a behaviour:
public class Counter1 implements ICount {
//Fields, Getters, Setters
#Overide
public int count() {
//I don't wanna count, so I return 4.
return 4;
}
}
On the other hand, Counter2 has a different oppinion of what should count do:
public class Counter2 implements ICount {
int counter; //Default initialization to 0
//Fields, Getters, Setters
#Overide
public int count() {
return ++count;
}
}
Now, you have two classes implementing the same interface, so, how do you treat them equally? Simple, by using the first common class/interface they share: ICount.
ICount count1 = new Counter1();
ICount count2 = new Counter2();
List<ICount> counterList = new ArrayList<ICount>();
counterList.add(count1);
counterList.add(count2);
Or, if you want to save some lines of code:
List<ICount> counterList = new ArrayList<ICount>();
counterList.add(new Counter1());
counterList.add(new Counter2());
Now, counterList contains two objects of different type but with the same interface in common(ICounter) in a list containing objects that implement that interface. You can iterave over them and invoke the method count. Counter1 will return 0 while Counter2 will return a result based on how many times did you invoke count:
for(ICount current : counterList)
System.out.println(current.count());
You can't call a method from all the objects that happen to implement a certain interface at once. You wouldn't want that anyways. You can, however, use polymorphism to refer to all these objects by the interface name. For example, with
interface A { }
class B implements A { }
class C implements A { }
You can write
A b = new B();
A c = new C();
Interfaces don't work that way. They act like some kind of mask that several classes can use. For instance:
public interface Data {
public void doSomething();
}
public class SomeDataStructure implements Data {
public void doSomething()
{
// do something
}
}
public static void main(String[] args) {
Data mydataobject = new SomeDataStructure();
}
This uses the Data 'mask' that several classes can use and have certain functionality, but you can use different classes to actually implement that very functionality.
The crux would be to have a list that stores every time a class that implements the interface is instantiated. This list would have to be available at a level different that the interface and the class that implements it. In other words, the class that orchestrates or controls would have the list.
An interface is a contract that leaves the implementation to the classes that implements the interface. Classes implement the interface abide by that contract and implement the methods and not override them.
Taking the interface to be
public interface Model {
public void onUpdate();
public void onClick();
}
public class plugin implements Model {
#Override
public void onUpdate() {
System.out.println("Pluging updating");
}
#Override
public void onClick() {
System.out.println("Pluging doing click action");
}
}
Your controller class would be the one to instantiate and control the action
public class Controller {
public static void orchestrate(){
List<Model> modelList = new ArrayList<Model>();
Model pluginOne = new plugin();
Model plugTwo = new plugin();
modelList.add(pluginOne);
modelList.add(plugTwo);
for(Model model:modelList){
model.onUpdate();
model.onClick();
}
}
}
You can have another implementation called pluginTwo, instantiate it, add it to the list and call the methods specified by the interface on it.

Can I create an object for Interface?

Is it possible to create an object for an interface? If yes, how is it done?
According to my view the following code says that we can:
Runnable r = new Runnable() {
// some implementation
}
This is not creating the instance of Interface, it is creating a class that implements interface. So when you write:
Runnable runnable = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
}
};
You are actually a creating a class that is implementing the Runnable interface.
You need to follow all rules here, here, we are overriding the run method for Runnable. There is similar thing for abstract class also. We can test using an example:
public abstract class AbstractClass {
public void someMethod() {
System.out.println("abstract class");
}
}
and another class i.e. TestClass:
public class TestClass {
public static void main(String[] args) {
AbstractClass abstractClass = new AbstractClass() {
public void someMethod() {
System.out.println("concrete class method");
}
};
abstractClass.someMethod();
}
}
This will create the instance of a subclass in which we are overriding someMethod();
This program prints:
concrete class method
This proves we are creating the instance of subclass.
You can't instantiate an interface directly, but you can instantiate a class that implements that interface:
public class RunClass implements Runnable {
// Class implementation
}
Runnable r = new RunClass();
This is basically the same as what you're doing inline. The brackets after new Runnable() will contain your implementation inline.
You can create an anonymous inner class:
Runnable r = new Runnable() {
#Override
public void run() {
}
};
Therefore you create a new class which implements the given interface.
Is it possible to creating object for an interface?
No. The code you've shown creates an object from an anonymous class, which implements the interface. Under the covers, the JVM actually creates a class implementing the interface, and then creates an instance of that class.
The "anonymous" class generated will actually have a name, based on the name of the class in which this code appears, for instance YourClass$1 or similar. E.g.:
public class AnonymousName {
public static final void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
}
};
System.out.println(r.getClass().getName());
}
}
...outputs
AnonymousName$1
(At least on Oracle's JVM; I don't know if the naming convention is in the JLS or if it's JVM-specific behavior.)
Here's my understanding.
An interface
public Interface SomeInterface{
}
You can declare an Object for an interface.
SomeInterface anObject;
You cannot instantiate this object directly using this interface.
However, let's say you have a class that implements this interface.
public class SomeClass implements SomeInterface {}
Then you can do this,
anObject = new someClass();
(This is conceptually of course (like pseudocode) actual code may vary depending on your classes and access modifiers etc.)
I'll update as to why exactly we are doing this/what the point is as soon as I find out.
Note: Some of this has been mentioned in above answers, just want the OP to know this whole thing too.
we can not instatiate the interface (since do not have constructor).
What you are seeing is an anonymous inner class.
it’s creating an instance of a new, anonymous,implementer of Runnable class.
Because an anonymous class definition is an expression, it must be part of a statement.

Categories