如何消除对 Java Beans 的硬依赖

How to eliminate hard dependecies on Java Beans

我有一个关于 DIP 原理的问题。其中一条准则说我们不应该保留对具体 class 的引用(如果它发生变化,那么我将不得不修改所有使用它的客户端)。那么,当我使用 POJO 时,我可以遵循这个指南吗?例如:

我有一个具有某些属性的 Bean 'Foo'(它可以代表一个域对象)

class Foo {  
   private String one;   
   private String two;

  //getters and setters
}

多个客户端实例化该对象,例如将其持久化到数据库中

   class Client1 {   

      private FooDao dao;

      Client1(FooDao dao){     
         this.dao = dao;
      }  

      public void persist() {    
         //hard coding
         Foo foo = new Foo();   
         foo.setOne("something...");    
         dao.save(foo); }     
       } 

       class Client2 {   

         private FooDao dao;

          Client2(FooDao dao){   
            this.dao = dao;

           }  

        public void persist() {   
           Foo foo = new Foo();   
           foo.setOne("something...");   
           foo.setTwo("something...")    
           dao.save(foo); 
         }
       }

如果我向 'Foo' class 添加或更改任何属性,则每个客户端都必须更改,所以请遵循此指南,我如何才能避免这种情况?

谢谢!

您需要定义要添加的方法的功能。

interface Functionality {
public void persist();
}

除了manager之外的每个class都需要实现接口:

 class Client1 implements Functionality{   
  //Your code..
}

添加一个高级 class 高级 classes 不能直接与低级一起工作 classes:

Class ManageClients{
    Functionality func;

    public void setClient(Functionality f) {
        func= f;
    }


    public void manage() {
        func.persist();
    }
};
  • ManageClients class 添加客户端时不需要更改。

  • 影响 ManageClients class 中存在的旧功能的风险最小化,因为我们不更改它。

  • 无需为 ManageClients class 重做单元测试。

我觉得你有点字面意思了。

我有幸参加了 Venkat Subramaniam 的演讲,其中谈到了 DIP。

当你说你应该依赖抽象而不是具体化时,你是对的,但在我那次演讲的笔记中,我有脚注,"take this with a grain of salt."

在你的情况下,你会想要对此持保留态度,因为这里有相当强烈的代码味道 - 你正在向所有需要它的消费者公开这个 bean 的使用,这隐式地创建对它的依赖。这违反了 Single Responsibility Principle 因为这个 bean 被用在比 可能 应该用的更多的地方。

因为你似乎在谈论数据库抽象,也许你想研究一个 DTO ,它会在服务之间公开以在它们之间传递信息,并让你的 bean 处理内部结构.

就你的观点...

if it change[s] then I'll have to modify all clients that use it

...如果您删除 功能,则为真。如果您添加新功能,您可以让您的下游客户忽略该功能。如果您想更改 现有 功能,您必须允许客户端迁移路径。

@chrylis 的评论是正确的。 Robert Martin 在 Clean Code: Objects and Data Structures 的第 6 章中对此进行了介绍。

Objects hide their data behind abstractions and expose functions that operate on that data. Data structures expose their data and have no meaningful functions. (page 95)

OOP 的定义,即一切都是对象,没有数据结构,是幼稚的。

Mature programmers know that the idea that everything is an object is a myth. Sometimes you really do want simple data structures with procedures operating on them. (page 97)

那么公开数据和行为的 类 呢?

Confusion sometimes leads to unfortunate hybrid structures that are half object and half data structure. They have functions that do significant things, and they also have either public variables or public accessors and mutators that, for all intents and purposes, make the private variables public, tempting other external functions to use those variables the way a procedural program would use a data structure. Such hybrids make it hard to add new functions but also make it hard to add new data structures. They are the worst of both worlds. Avoid creating them. (page 99)

对于原始问题:依赖倒置原则适用于对象,不适用于 Java Beans 等数据结构。