mercredi 9 mai 2018

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. :-)

Aucun commentaire:

Enregistrer un commentaire