Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这是反模式还是违反了一些设计原则?_Java_Design Patterns_Coding Style_Anti Patterns_Design Principles - Fatal编程技术网

Java 这是反模式还是违反了一些设计原则?

Java 这是反模式还是违反了一些设计原则?,java,design-patterns,coding-style,anti-patterns,design-principles,Java,Design Patterns,Coding Style,Anti Patterns,Design Principles,我尝试了设计模式和原则,但有一个问题。 在此之前,很抱歉我的编码风格不好 在本例中,我有一个类似ITest的接口: public interface ITest { public void method1(); } 然后将方法和字段(如果有)实现到具体的B类中,如下所示: public class B implements ITest { //This is the method from the interface @Override public void

我尝试了设计模式和原则,但有一个问题。 在此之前,很抱歉我的编码风格不好

在本例中,我有一个类似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
    }
}
现在在应用程序代码中,我将其放在如下位置:

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()));
    }
}
此外,我还可以封装、继承和抽象其他方法、字段等。 这意味着,我可以创建更复杂、更灵活的层次结构

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


感谢收看。:-)

将返回
B
的方法添加到
B
实现的接口
ITest
中肯定是一个糟糕的设计选择,因为它迫使其他类实现
ITest
返回
B

public class C implements ITest {
    @Override
    public B hook()
    {
        return // What do I return here? C is not a B
    }
    ...
}
您的第一选择更好:

B test1 = new B();
C test2 = new C();
这是一种反模式、糟糕的设计原则,还是我们可以 从中受益

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

问题源于这样一个事实:您将
ITest
B
紧密耦合。假设我想创建一个新的
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
。那么你在增加什么价值呢?你只是让界面变得不那么连贯和混乱。

你可能有更好的机会在@Federuco klez Culloca上得到答案谢谢你的提示