java - 这是一种反模式还是违反了一些设计原则?
问题描述
我尝试使用设计模式和原则并有一个问题。之前,对不起编码风格的坏习惯!
在这种情况下,我有一个类似 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()));
}
}
此外,我可以封装、继承和抽象其他方法、字段等。这意味着,我可以创建更复杂和灵活的层次结构。
我现在的问题是:这是一种反模式、糟糕的设计原则,还是我们可以从中受益?
谢谢收看。:-)
解决方案
这是一种反模式、糟糕的设计原则还是我们可以从中受益?
是的,这是一个糟糕的模式。
问题源于您紧密耦合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
. 那么你在增加什么价值呢?您只是使界面变得不那么连贯且更加混乱。
推荐阅读
- google-tag-manager - 使用 GTM 设置 Magento 2 GA4 (Google Analytics 4)
- oauth-2.0 - Google 登录 OAuth 2 域验证
- python - from scipy.optimize._shgo_lib.sobol_seq import Sobol 不起作用
- javascript - 导入别名“主题”的循环定义
- hl7-fhir - 如何使用 HAPI 为 Provenance 实现 revinclude
- automation - 自动下载和播放 ftp 内容 - 图像
- google-play-services - 如何在没有 GMS 许可的情况下使用 android play service api?
- asp.net-core - 在.net核心中使用Nlog进行双重日志记录?
- jmeter - java.net.SocketException:JMeter 上的连接重置
- php - 使用内联 if 语句禁用 swiper.js 自动播放