Nesneler arabirimin yalnızca bir bölümünü kullandığında arabirimleri nasıl yapılandırabilirim?


9

Her ikisi de aynı tablo güncelleştiren bir veritabanı erişim nesnesi gerektiren iki sınıf var bir proje var. Çerçevenin ve projenin kısıtlamaları, bu iki sınıfı birleştiremeyeceğim şekilde yapar. Aşağıda kurulumun nasıl olduğunu gösteren bir vaka oluşturdum. Sınıf A'nın kaydı güncelleyebilmesi ve okuyabilmesi gerekirken, Sınıf B'nin kaydı güncelleyebilmesi ve silebilmesi gerekir.

Sınıfları oldukları gibi kullanırsam, gayet iyi çalışır, ancak sınıfların her birinin uygulanması için kullanmadığı işlevsellik gerektirdiği gerçeğiyle ilgili bir sorun yaşıyorum. Örneğin, A sınıfını kullanmak için, asla çağrılmasa bile, silme işlevini uygulayan bir dao iletmem gerekiyor. Benzer şekilde, B sınıfını okuma işlevini uygulayan bir dao'dan geçmek zorundayım ama asla çağrılmayacak.

Başkalarını devralan arabirimlere sahip olarak yaklaşmayı düşündüm (IReaddao, IUpdatedao, IDeletedao, miras alınacak olan daos), ancak bu yaklaşım temel olarak her işlev kombinasyonu için farklı bir arabirim gerektirecektir (IUpdateAndRead, IReadAndDelete, IReadAndUpdate ... )

Uygulamayı veritabanıyla eşleştirmek istemediğim için dao için bir arayüz kullanmak istiyorum. Kimsenin bilmesini istediğim şeyi gerçekleştirmek için bir model veya yöntem var mı? Şimdiden teşekkürler.

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
Neden bunları kullanan her sınıfın ihtiyaç duyduklarını kullanması yerine, her kombinasyon için ayrı arabirimlere ihtiyacınız var?
yitzih

Yukarıdaki durumda, IDao'yu A'nın yapıcısına iletmek yerine, IUpdate ve IRead'i uygulayan bir nesneyi geçmek zorunda kalacağım, yani "dao" örnek değişkeninin türü ne olurdu? IUpdateAndReaddao gibi bir şey olması gerekmez mi? Hala bir arayüz olması gerekiyor çünkü ben veritabanına özgü bir uygulama almak söylüyorum ben sınıf db için birleştiğinde. Sorduğun şey bu mu?
jteezy14

3
Bu Arayüz Ayrışma İlkesi (mükemmel bir örnek olduğunu düşünüyorum Idan SOLID). Üzerine biraz okumak isteyebilir.
Christopher Francisco

Yanıtlar:


10

Christopher'ın yorumuna göre, arayüzleri ayırmak muhtemelen biraz daha iyidir . Eğer en azından gerekir Yani IReadDao, IDeleteDaove IUpdateDao. Üç sınıfa ihtiyacınız olmadığını unutmayın; kod tabanının bu şekilde birleştirilmesi mantıklıysa, her üç arabirimi de uygulayan büyük bir DAO sınıfına sahip olabilirsiniz.

Kombinatoryal patlamayı önlemek için (örneğin bir ihtiyacını önlemek için IReadUpdate, IDeleteUpdatevb arayüz) ayrı arayüzler yapıcı enjeksiyon sağlayabileceği (iki kez farklı parametreler aynı nesneyi geçirebilir), ya da iki veya daha fazla arayüzleri destekleyen tek bir nesne sağlamak kullanarak genel bir yöntem çağrısı extends.

Yapıcı enjeksiyonu:

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....
}

Jenerik yöntem kullanılarak setter enjeksiyonu:

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

Setter enjeksiyonunu kullanırken, Initializedao ​​işlevinde ayarladığım örnek değişkeni nasıl bildirebilirim?
jteezy14

İki örnek değişkenine (biri silme işlemleri için, biri güncellemeler için) ihtiyacınız olacak ... daoher ikisine de atama .
John Wu

Ah evet, bu mantıklı. Harika cevap için çok teşekkürler!
17:24
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.