Thread-safe inheritance - java

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.

Related

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();

Effective design for related classes that use unrelated classes

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.

Java inheritance not behaving as expected

The following context is needed: The purpose of this way of coding is to avoid if-else statements and instanceof; which is always a bad idea.
I have 3 classes with the following signatures:
abstract class A {}
class B extends A {}
class C extends A {}
Then I have another class with the following structure:
class MyClass {
private final A model;
public MyClass(A m) {
this.model = m;
}
public void doSomething() {
System.out.println(this.model instanceof C); //TRUE!!
execute(this.model);
}
private void execute(A m) {
System.out.println("noo");
}
private void execute(C m) {
System.out.println("yay");
}
}
And finally the contents of my main:
public static void main(String... args) {
C mod = new C();
MyClass myClass = new MyClass(mod);
myClass.doSomething();
}
Now the problem; the execute(C) method never gets executed, it's always the execute(A) method. How can I solve this? I cannot change the signature of the execute(A) method to execute(B) since that would give an error saying java "cannot resolve method execute(A)" at MyClass#doSomething.
Method overloads are resolved at compile time. At compile time, the type of m is A, so execute(A m) gets executed.
In addition, private methods are not overridable.
The solution is to use the Visitor pattern as suggested by #OliverCharlesworth.
Your code illustrates the difference between a static and a dynamic type of an object. Static type is what's known to the compiler; dynamic type is what's actually there at runtime.
The static type of your model field is A:
private final A model;
That is, the compiler knows that A itself or some of its implementations is going to be assigned to model. The compiler does not know anything else, so when it comes to choosing between execute(A m) and execute(C m) its only choice is execute(A m). The method is resolved on the static type of the object.
instanceof, on the other hand, understands the dynamic type. It can tell that the model is set to C, hence reporting the true in your printout.
You can solve it by adding a method to A and overriding it in B and C to route to the proper execute:
abstract class A {
public abstract void callExecute(MyClass back);
}
class B extends A {
public void callExecute(MyClass back) {
back.execute(this);
}
}
class C extends A {
public void callExecute(MyClass back) {
back.execute(this);
}
}
class MyClass {
private final A model;
public MyClass(A m) {
this.model = m;
}
public void doSomething() {
System.out.println(this.model instanceof C); //TRUE!!
model.callExecute(this.model);
}
public void execute(B m) {
System.out.println("noo");
}
public void execute(C m) {
System.out.println("yay");
}
}
Note that both implementations call
back.execute(this);
However, the implementation inside B has this of type B, and the implementation inside C has this of type C, so the calls are routed to different overloads of the execute method of MyClass.
I cannot change the signature of the execute(A) method to execute(B)
Also note that now you can (and should) do that, too, because callbacks are performed to the correct overload based on type of this.
Method overloading is a compile time polymorphism. Thus, for calling method execute(C) you need to define your model as class C.
It's better to define method execute() in class A and override it in subclasses.
abstract class A {
abstract void execute();
}
class B extends A {
public void execute(){};
}
class C extends A {
public void execute(){};
}
And then:
class MyClass {
private final A model;
public void doSomething() {
model.execute();
}
This much better way to use polymorphism to avoid if-else statements and instanceof checking
You are sending object of type C as an object of type A in constructor( you've done upcasting) and assigning it to a reference to type A(which will result in calling only execute(A) method).You could check if the object is a instance of C and depending on the outcome, call the desired method. You could do it like this
public void doSomething(){
System.out.println(model instanceof C);
if (model instanceof C) execute((C)model);
else
execute(model);
}

Java wrapper: overriding a method called in the super constructor

I want to wrap a class in Java but the problem is as follows:
public class A {
public A() {
doSomething();
}
public void doSomething() {
}
}
Now when I try to wrap this class and delegate all methods to the wrapper
public class Wrapper extends A {
private final A a;
public Wrapper(A a) {
super();
this.a = a;
}
#Override
public void doSomething() {
this.a.doSomeThing();
}
}
of course I get a NPE as 'a' is still null as it is set after the super()-call which calls the overriden doSomething() method. Is there any solution for this problem? The only thing that came to my mind was making a factory method and setting a static variable holding the reference to a but this seems ugly to me.
I'd recommend changing the code so that doSomething is not called in the constructor.
Alternatively split A into an interface and implementation Wrapper implements the interface and does not inherit from A
public interface IA {
public void doSomething() {
}
}
public class A implements IA {
public A() {
doSomething();
}
public void doSomething() {
}
}
public class Wrapper implements IA {
private final IA a;
public Wrapper(IA a) {
this.a = a;
doSomething();
}
#Override
public void doSomething() {
a.doSomeThing();
}
}
Change your Wrapper this way. You do not need to hold A explicitly. The expression super is the same as your filed:
class Wrapper extends A {
public Wrapper() {
}
#Override public void doSomething() {
super.doSomething();
}
}
Or otherwise extract an interface and change your code like this:
class Wrapper implements AA {
private final AA child;
public Wrapper(AA child) {
this.child = child;
}
#Override public void doSomething() {
child.doSomething();
}
}
class A implements AA {
public A() {
doSomething();
}
#Override public void doSomething() {}
}
interface AA {
public void doSomething();
}
A way for this to be avoided is by exposing an init method (or any other name) from your base class (if you are in control of its logic). Then move the call from the constructor to the init method:
public class A {
public A() {
}
public void init() {
doSomething();
}
public void doSomething() {
}
}
You should update your code to call the init method after making an instance of the class, which may be a bit of boilerplate:
A instance = new Wrapper();
instance.init();
instead of just
A instance = new Wrapper();
If you use Spring and DI, you can specify an init-method in the xml context, so Spring will call it for you when it resolves the dependency.
In case the doSomething method is public, and accepts no arguments, you can use it directly instead of the init method both in code and with Spring.
In general, use of overridable methods in a constructor is an anti-pattern, due to the problem you have encountered. There is no way to predict how a derived class will override the methods and if they rely on non-initialized resources, then you are in trouble.
two small changes, young one you need
public class Wrapper extends A {
private final A a;
public Wrapper(A a) {
super();
this.a = a;
//this will execute method doSomething wrom Wrapper class after variable a is set
doSomething();
}
#Override
public void doSomething() {
//this will prevent to call metod from superclass constructor, bit risky thou
if (a!=null)
this.a.doSomething();
}
}
but overriding methods which are called in constructo is generally bad practice and smells terrible

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.

Categories