객체가 인터페이스의 일부만 사용할 때 인터페이스를 어떻게 구성합니까?


9

동일한 테이블을 업데이트하는 데이터베이스 액세스 객체가 필요한 두 개의 클래스가있는 프로젝트가 있습니다. 프레임 워크와 프로젝트의 제약으로 인해이 두 클래스를 결합 할 수 없습니다. 아래에서 설정 방법을 보여주는 사례를 만들었습니다. 클래스 A는 레코드를 업데이트하고 읽을 수 있어야하고 클래스 B는 레코드를 업데이트하고 삭제할 수 있어야합니다.

클래스를 그대로 사용하면 제대로 작동하지만 각 클래스에는 구현에 사용되지 않는 기능이 필요하다는 사실에 문제가 있습니다. 예를 들어 클래스 A를 사용하려면 결코 호출되지 않더라도 delete 함수를 구현하는 dao를 전달해야합니다. 마찬가지로, 읽기 기능을 구현하는 클래스 B a dao를 전달해야하지만 호출되지는 않습니다.

다른 인터페이스를 상속받는 인터페이스 (IReadDao, IUpdateDao, IDeleteDao는 상속되는 daos)를 사용하여 접근하는 방법에 대해 생각했지만이 접근법에는 기본적으로 각 기능 조합 (IUpdateAndRead, IReadAndDelete, IReadAndUpdate ...)마다 다른 인터페이스가 필요합니다. )

응용 프로그램을 데이터베이스와 연결하고 싶지 않기 때문에 dao에 대한 인터페이스를 사용하고 싶습니다. 내가 아는 바를 달성하기위한 패턴이나 방법이 있습니까? 미리 감사드립니다.

class IDao {

  void update(ModelDao model);
  void delete(String guid);
  ModelDao read(String guid);

}

Class A {

  private IDao dao;

  public A(IDao dao) {

    this.dao = dao;

  }

  public void doStuff() {

    ModelDao model = new ModelDao();

    ...

    dao.update(model);

  }

  public void readThenDoSomething(String id) {

    ModelDao model = dao.read(id);

    ...

  }

}

Class B {

  private IDao dao;

  public B(IDao dao) {

    this.dao = dao;

  }

  public void makeUpdate() {

    ModelDao model = new ModelDao();

    ...

    dao.update(model);

  }

  public void delete(String id) {

    dao.delete(id);

  }

}

2
클래스를 사용하는 각 클래스가 필요한 클래스를 구현하는 것과 달리 각 조합에 대해 별도의 인터페이스가 필요한 이유는 무엇입니까?
yitzih

위의 경우 IDao를 A의 생성자로 전달하는 대신 IUpdate 및 IRead를 구현하는 객체를 전달해야하는데 인스턴스 변수 "dao"의 유형은 무엇입니까? IUpdateAndReadDao와 같을 필요는 없습니까? 데이터베이스와 관련된 구현을 수행하도록 지시하면 클래스를 db에 연결했기 때문에 여전히 인터페이스가 필요합니다. 그게 당신이 요구 한 것입니까?
jteezy14

3
나는 이것이 인터페이스 분리 원리 (에서 Ifrom SOLID) 의 완벽한 예라고 생각합니다 . 그것에 대해 조금 읽고 싶을 수도 있습니다.
Christopher Francisco

답변:


10

Christopher의 의견에 따르면 인터페이스분리하는 것이 약간 더 좋습니다 . 당신이 최소한 필요 그래서 IReadDao, IDeleteDao하고 IUpdateDao. 반드시 세 개의 클래스가 필요하지는 않습니다. 코드 기반을 그러한 방식으로 결합하는 것이 합리적이라면 세 가지 인터페이스를 모두 구현하는 하나의 큰 DAO 클래스를 가질 수 있습니다.

조합 폭발을 방지하기 위해 (예를 들면은에 대한 필요성을 피하기 위해 IReadUpdate, IDeleteUpdate등 인터페이스)는 별도로 인터페이스 생성자 주입에 제공 할 수있다 (이 두 가지 매개 변수와 같은 물체를 통과 할 수있다), 또는 둘 또는 그 이상의 인터페이스를 지원하는 단일 목적을 제공한다 를 사용하여 일반 메소드 호출에서 extends.

생성자 주입 :

class MyDaoLibrary : IUpdateDao, IInsertDao, IDeleteDao {
    //Etc....
}

class A
{
    //It is OK if the IoC container factory provides the same instance for both parameters.
    a(IUpdateDao dao1, IDeleteDao dao2) {
        this.updater = dao1;
        this.deleter = dao2;
    }
    //Etc....
}

일반적인 방법을 사용한 세터 주입 :

<T extends IUpdateDao & IDeleteDao> void InitializeDao(T dao)  //Pass a single object that implements both IUpdateDao and IDeleteDao

setter injection을 사용할 때 InitializeDao 함수에서 설정하고있는 인스턴스 변수를 어떻게 선언합니까?
jteezy14

두 개의 인스턴스 변수 (하나는 삭제, 하나는 업데이트) dao가 필요합니다. 둘 다에 할당하십시오 .
존 우

아 맞다. 큰 답변에 감사드립니다!
jteezy14
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.