Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call virtual method in constructor - better design

I declared an ISerializable interface in java.

I basically have 2 methods: serialize(), and deserialize(byte[] buffer).

public interface ISerializable{
    byte[] serialize();
    deserialize(byte[] buffer);
}

and here is an example of a class implementing this interface:

public class MySerializableClass implements ISerializable{   
    byte[] serialize(){bla bla}
    deserialize(byte[] buffer){bla bla};
}

Ideally, I would like the call to deserailize to be implicit. i.e. when calling the constructor MySerializableClass(byte[] buffer), it would call the correct deserialize with the buffer passed. like that:

public abstract class AbstractSerializable {
    public abstract byte[] serialize();
    public abstract void deserialize(byte[] buffer);
    public AbstractSerializable (){}
    public AbstractSerializable (byte[] buffer){
        deserialize();
    }
}

public class MySerializableClass extends AbstractSerializable {
    byte[] serialize(){bla bla}
    deserialize(byte[] buffer){bla bla};
}

AFAIK it is problematic to call virtual methods within the constructor and this might end up with an undefined behavior. so currently, I am doing the following:

MySerializableClass myClass = new MySerializableClass();
myClass.deserialize(buffer);

or by using a dedicated static method that is defined for each class that extends my interface (and basically just do the above 2 lines of code):

MySerializableClass myClass = MySerializableClass.CreateMySerializableClass(buffer); 

My questions is: is there any elegant way to do that without the need to define a dedicated static method for each class implements ISerializable? Is there any design pattern that solves this issue?

Note: My serialization is unique so I need to write it on my own, and also for technical reasons I can only use very basic features of Java. ( no annotations,templaates metadata, etc.) so I need a very basic OOP solution.

like image 632
user844541 Avatar asked Sep 04 '26 13:09

user844541


1 Answers

I find your solution elegant enough, what you're doing is a Factory, which is an elegant way to solve your problem. You can keep your constructor private, and always retrieve the objects through the factories

public class MySerializableClass extends AbstractSerializable {

    private MySerializableClass(){

    }

    public static MySerializableClass CreateMySerializableClass(final byte[] buffer){
        MySerializableClass result = new MySerializableClass();
        result.deserialize(buffer)
        return result;
    }

    byte[] serialize(){bla bla}

    deserialize(byte[] buffer){bla bla};
}
like image 133
Guillermo Merino Avatar answered Sep 06 '26 03:09

Guillermo Merino



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!