我们可以使用依赖倒置原则实现 100% 抽象吗?

时间:2021-04-21 11:15:31

标签: java android solid-principles

在我的日常编程中,我尽量遵循可靠的原则和其他设计模式,但在某些情况下会变得困难,特别是使用依赖倒置原则,对于层次结构类,创建工厂类并在那里存储对象可能很容易,也与 singleton 或 builder 相同,但是当您在方法中使用单个类对象时会出现问题,该方法会不时更改并且同样没有层次关系

//这里在 newTaskFor() 方法中,浸入原则被违反了 那么如何在日常程序中解决此类问题,或者在容器类中使用 new Keyword 是可以的

    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
     return new FutureTask<T>(callable);  //violating Dip principle
     }

/**
 * @throws RejectedExecutionException {@inheritDoc}
 * @throws NullPointerException       {@inheritDoc}
 */
public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

1 个答案:

答案 0 :(得分:0)

在某个时间点总有凝结物。如果您想对所有内容应用 DIP,那么几乎所有类型都必须一遍遍地隐藏在高级特定接口后面,这不切实际。

例如,声明 newTaskFor 的高级模块可以很好地制作自己的 Future 抽象,这些抽象不会直接耦合到 Java 的本机 API,但这可能会很多工作收益微乎其微?

我经常问自己这个问题的一个很好的例子是,当我设计了一个简单的网络爬虫库时,它必须大量操作 HTML 文档。我可以选择耦合到像 Jsoup 这样的特定库,或者创建我自己的抽象以避免紧密耦合。由于我必须在最后支持复杂的文档查询和操作,我发现在 Jsoup 之上制作另一个抽象层非常不切实际,我必须重新定义几乎所有节点接口。

在这些情况下有效抽象的关键是只关注系统真正需要的 API 部分,其余部分并确保以特定于域的方式表达该抽象。如果您最终模仿整个 API,那么无论如何您的抽象很可能会受到特定实现的高度影响。 如果您发现需要底层库的所有功能,那么将其抽象出来可能代价太大。

编辑:

我刚刚检查了一下,似乎我在第三段中撒了谎,最终我制作了一个如下所示的 API(几年前,我似乎只支持我拥有的最小用例而不是复杂的库),但老实说,Scraper 只会支持极其基本的提取,而这种抽象最终可能弊大于利。

enter image description here