6

既存のプロジェクトには多くの DAO があります (現在はインターフェイスがありませんが、変更される可能性があります)。各 DAO クラスに Spring 管理の Bean を接続してサービス層に注入するのではなく、次のような種類の DAO の「ファクトリー」を用意します。

public class DAOFactory {
private static DAOFactory daoFac;

static{
    daoFac = new DAOFactory();
}

private DAOFactory(){}

public static DAOFactory getInstance(){
    return daoFac;
}

public MyDAO1 getMyDAO1(){
    return new MyDAO1();
}

    public MyDAO2 getMyDAO2(){
    return new MyDAO2();
}
    ...

(MyDAO1 と MyDAO2 は具象クラスであることに注意してください)

これにより、サービス層内で DAO メソッドを簡単に追加/呼び出すことができます。1.) DAO インターフェイスをプロパティとしてサービス クラスに追加します。2.) 構成を介して DAO 実装をサービス メソッドに接続します。(また、1 つのサービス クラスで複数の DAO を使用することもあります)。

DAOFactory.getInstance().getMyDAO1().doSomething();

これまでのところ、この戦略はうまく機能しています (実装を切り替える必要はあまりありませんでした) が、新しく始めることができた場合、より良い方法があるかどうか疑問に思っています。DAO を Bean として自動配線することを検討しましたが、使用されている DAO を表すために、各サービス クラスにプロパティを作成する必要があります。そして、大規模なプロジェクトでは、bean の自動配線を開始することをためらっています。すべての開発者に可視性を提供する必要があります。

a.) 実装に密結合しているが、コード/構成のオーバーヘッドが少ないことと、b.) インターフェースに疎結合しているが、多くのコード/構成のオーバーヘッドが必要であることの間でフリップフロップしているように感じます。

私が行方不明になっているより良い方法はありますか?その中間の何か?意見歓迎。

4

5 に答える 5

5

すべての DAO を Spring 管理コンポーネントとして保持し、疎結合のためにサービスに注入します。大規模なプロジェクトで Bean の自動配線が悪いと思うのはなぜですか?

各 DAO クラスに @Component のアノテーションを付けてMyDao mydao = factory.getmyDao()

@Autowired MyDao myDao;

コーディング/構成のオーバーヘッドはあまりありません。

于 2012-12-06T18:33:07.620 に答える
3

私は自分のプロジェクトでこれまでに 2 つの異なるアプローチをとってきましたが、何が「ベスト」かについてはまだ結論が出ていません。そして、「ベスト」ではなく、おそらく「あなたのニーズにとってベスト」があるかもしれません。

まず、基本サービス クラスを使用しました。

public abstract BaseService {
    @Autowired FooDAO fooDao;
    @Autowired BarDAO barDao;
    . . .
    . . .
    protected getFooDAO() {
        return this.fooDao;
    }
}

それから私のサービスクラスでは、私は簡単に書くことができます

Foo foo = getFooDAO().uniqueById(id);

これは機能し、dao インスタンス変数のすべてのオートワイヤリングおよびアクセサー クラスからサービスを整然と保ちます。問題は、各サービスでこの基本クラスのコピーを取得したことです。率直に言って、それほど大したことではありません。しかし、本質的にDIの理由が構成を促進することである場合、継承よりも構成を使用していないため、一種のコード臭も生じます。

同僚があなたのようなファクトリを提案し、それを ServiceProvider と呼びました。これをサービスに自動配線します。

@Component
public class ServiceProvider {
    @Autowired FooDAO fooDao;
    public FooDAO getFooDAO() {
        return this.fooDao;
    }
    . . .
    // yadda yadda
}

次に、あなたが持っているようなものがあります:

Foo foo = getServiceProvider().getFooDAO().uniqueById(id);

そして、それはかなり醜いものであり、実際には明確にはなりません. そのため、プロバイダーのインスタンスだけを使用して、sp のような短くてわかりやすい名前を付けることにしました。次に、取得します

Foo foo = this.sp.getFooDAO().uniqueById(id);

繰り返しますが、それは機能します。そして、それはおそらくより良いデザインです。また、DAO を各 Service ではなく 1 か所でのみ自動配線しますが、どちらにしてもそれほど問題ではありません。しかし、Me Feeling Betterはプロジェクトの要件ではありませんが、気分が良くなります (しかし、そうあるべきだと思いませんか?)。

この2つを組み合わせようと考えていました。BaseService を変更して ServiceProvider を自動配線し、醜い呼び出しをラップします。

public abstract BaseService {
    @Autowired ServiceProvider serviceProvider;

    protected getFooDAO() {
        return this.serviceProvider.getFooDAO();
    }

    protected getBarDAO() {
        return this.serviceProvider.getBarDAO();
    }
}

私の意見では、各DAOを各サービスに自動配線する必要はありませんが、各サービスにはこれらすべての参照のコピーがありません。まったくばかげた懸念。

私が抱えている問題は、デバッガーでコードをステップ実行することです。これらの getWhateverDAO() 呼び出しのそれぞれにステップ インおよびステップ アウトするのは面倒です。

しかし、それが私がこの問題を抱えているところです。率直に言って、私はこれについて考えるのに多くの時間を費やしていると思います。なぜなら、これは私たちのアプリケーションがもたらす本当に困難な問題をすべて回避する素晴らしい方法だからです。

于 2012-12-06T19:51:53.567 に答える
1

良い質問。

使い始めたのはとても残念だと思いますDAOFactory。Spring は非常に柔軟なファクトリなので、なぜ他のものが必要なのか本当にわかりません。春の自動配線には多くの利点があり、インターフェイスを必要としないため、春を使用して DAO にアクセスするように簡単に切り替えることができます。私見それは減少しませんが、他の開発者の可視性を向上させます.

さらに、DAO レイヤーのリファクタリングを検討している場合は、Google コードから GenericDAO を参照してください: http://code.google.com/p/hibernate-generic-dao/

私はこの図書館でとても良い経験をしました。時間を節約できます。実際には多くの DAO は必要ありません。必要な DAO は 1 つだけです。もちろん、汎用 DAO を Google コードからラップして、アプリケーション固有の用語と機能を追加できます。ただし、そこにエンティティ固有のコードを追加しないでください。エンティティ固有のコードはサービス層にある必要があります。Hibernate 基準 API を使用している場合は、脆弱な HQL や Hibernate との結合がなくなります。このライブラリは Hibernate と JPA の両方をサポートし、その API は非常にシンプルで強力です。

于 2012-12-06T18:37:46.993 に答える
0

1 つのサービスで使用する DAO が多すぎる場合は、1 つのサービスをより下位の (きめ細かい) サービスに分割することを検討する必要があります。

于 2012-12-06T18:35:53.940 に答える