web-dev-qa-db-ja.com

サービスおよびDAOレイヤーの責任と使用

現在、Springプラグインと休止状態を備えたStruts2を使用してWebアプリケーションを開発していますが、オンラインサンプルを見ているときに、サービスレイヤーとDAOレイヤーの使用を見てきましたが、サービスレイヤーとデータアクセスオブジェクトレイヤーの実際の用途は何ですか?サービス層がDAO層のメソッドを呼び出してCRUD操作を実行している場合。 DAOレイヤーのメソッドを直接呼び出すだけでは賢明ではないでしょうか?

このDaoとサービスレイヤーの例を見てみましょう

PeopleService

  @Transactional
    public class PeopleService {

        private PeopleDao pDao;

        public PeopleDao getPDao() { return pDao; }

        public void setPDao(PeopleDao peopleDao) { this.pDao = peopleDao;   }

        public void createPerson(String name){
            pDao.createPerson(name);
        }

        public List<Person> getPeople(){
            return pDao.getPeople();
        }

    }

PeopleDao

public class PeopleDao {

    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Session sess() {
        return sessionFactory.getCurrentSession();
    }

    public Person getPersonById(long id) {
        return (Person) sess().load(Person.class, id);
    }

    public void deletePersonById(long id) {
        sess().delete(getPersonById(id));
    }

    public void createPerson(String name) {
        Person p = new Person();
        p.setName(name);
        sess().save(p);
    }

    @SuppressWarnings("unchecked")
    public List<Person> getPeople() {
        return sess().createQuery("from Person").list();
    }

}

私の質問は、サービスレイヤーが代表的なDAOによってのみ注入され、そのメソッドを呼び出す場合、サービスレイヤーの実際の使用は何ですか?

30
user962206

ビジネスロジックがデータロジックよりも複雑な場合は、これらの2つのレイヤーを使用することをお勧めします。サービスレイヤーはビジネスロジックを実装します。ほとんどの場合、このレイヤーは、DAOオブジェクトからメソッドを呼び出すだけでなく、より多くの操作を実行する必要があります。また、アプリケーションを大きくすることを考えている場合、これがおそらく最良のソリューションです。

Cityエンティティを含めて、PeopleとCityの間に関係を作成するとします。以下に例を示します。

@Transactional
public class PeopleService {

    ....
    private PeopleDAO pDAO;
    private CityDAO cDAO;

    ...

    public void createPerson(String name, String city)
     throws PeopleServiceException {
        Person p = new Person();
        p.setName(name);

        City c = cDAO.getCityByName(city);
        if (c == null) throw new ServiceException(city + " doesn't exist!");
        if (c.isFull()) throw new ServiceException(city + " is full!");
        c.addPeople(p);

        sess().save(p);
        sess().save(c);
    }

    ...
}

この例では、データの一貫性をチェックするなど、より複雑な検証を実装できます。また、PersonDAOは変更されていません。

もう一つの例:

Springを使用したDAOおよびサービスレイヤー

サービス層パターンの定義

44
CarlosMecha

新しい要件や変化する要件に合わせてアプリケーションが成長する場合、ソフトウェアの2つの異なる側面(永続性-> DAO、ビジネスユースケース->サービス)に個別のレイヤーを使用することで、十分に対応できます。

1つの側面は、関係、検証、トランザクション、および多くのアクセスパターンを備えた永続性モデルです。

サービスは、非常に異なる粒度を持つビジネスユースケースによって駆動されます。最初は、DAOを呼び出して受信したデータ(Webページなど)を引き渡す以上のことはしない、非常に単純なサービスがあるかもしれません。しかし、これは時間の経過とともに変化する可能性があり、サービスは、ビジネスユースケースに対応するためにさらに多くのことを行うコラボレーションオブジェクトの小さなネットワークに成長します。 DAOを使用しない場合

  • サービスには、クエリオブジェクト、トランザクション処理、検証を処理するコードが含まれます。これらはすべて、実際のビジネス要件とは関係ありません。
  • サービスコードが乱雑に見えるため、コードのどの部分が実際にビジネス関連であるかを見つけるのは困難です
  • その後、永続性モデルを変更すると、多くのサービスが変更される可能性があります

また、永続性モデルを簡単に単体テストすることはできませんが、サービス層でのみテストを記述できます。デカップリングとカプセル化は、変更の影響を最小限に抑えるための重要な手法であることを忘れないでください。

正しく行われた場合、DAOレイヤーを使用しても実装のオーバーヘッドはあまり発生しないため、DAOレイヤーを使用するのに余計なコストはかかりません。それはすぐに報われ、あなたはこの専用レイヤーを持つことを非常に喜んでいるでしょう。

この記事をご覧ください: http://codeblock.engio.net/?p=18 。また、githubでホストされる完全な実装が付属しています

10
bennidi