首页 > 解决方案 > 这是一种反模式还是违反了一些设计原则?

问题描述

我尝试使用设计模式和原则并有一个问题。之前,对不起编码风格的坏习惯!

在这种情况下,我有一个类似 ITest 的接口:

public interface ITest
{
    public void method1();
}

然后将方法和字段(如果有)实现到具体的 B 类中,如下所示:

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");
    }
}

现在在应用程序代码中我把它放在这样的地方:

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
    }
}

您会看到 B 类中的 method2() 不可用,因为 ITest 的接口。现在,如果我需要这种“重要”的方法怎么办?有几种可能性。我可以在接口中抽象它或使 B 类抽象并扩展到另一个类等等,或者在 main() 方法中进行引用,例如:

B test = new B();

但这会违反原则。所以,我将界面修改为:

public interface ITest
{
    //A method to return the class-type B
    public B hook();
    public void method1();
}

并将实现放入 B 类:

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");
    }
}

现在在我的 main() 方法中,我可以使用一点挂钩或链接机制调用这两种方法,而无需引用新对象,也不会违反设计原则,并且我不需要额外的类来进行扩展或抽象。

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

此外,我可以封装、继承和抽象其他方法、字段等。这意味着,我可以创建更复杂和灵活的层次结构。

我现在的问题是:这是一种反模式、糟糕的设计原则,还是我们可以从中受益?

谢谢收看。:-)

标签: javadesign-patternscoding-styleanti-patternsdesign-principles

解决方案


这是一种反模式、糟糕的设计原则还是我们可以从中受益?

是的,这是一个糟糕的模式。

问题源于您紧密耦合ITestB. 假设我想创建一个新的实现ITest- 让我们称之为C

public class C implements ITest
{
    @Override
    public B hook()
    {
        // How do I implement this?
    }

    @Override
    public void method1()
    {
        System.out.println("method1");
    }
}

我们没有理智的方法可以实现这个方法。唯一合理的做法就是返回null。这样做会迫使我们界面的任何用户不断地执行防御性的空值检查。

如果他们每次都必须在使用该方法的结果之前进行检查,那么他们还不如执行一个instanceof并强制转换为B. 那么你在增加什么价值呢?您只是使界面变得不那么连贯且更加混乱。


推荐阅读