私は所有しているエンティティを扱うサービスをデカップリングするためのデザインパターンやコンベンションを探しています。テーマの作成を処理するThemeService
があるとします。最初はThemeService
は各ユーザーのUserData
のテーマをそのまま残していますが、要件は変更され、テーマはThemeCollection
などの他のエンティティによって所有されています。私の問題は、各ThemeService
は、「所有する」エンティティが何であれ、密接に結合されていることです。例:所有エンティティのサービスをデカップリングするためのデザインパターンは何ですか?
public class ThemeService{
//coupled to UserData
createTheme(Theme t, UserData u);
getTheme(String name, UserData u);
hasTheme(String name, Userdata u); //Theme name unique within a userdata.
validateTheme(Theme t, UserData u); //unique name per user, valid colors, etc.
}
public class UserDataService{
ThemeService tService; //component for themes
getUsername(UserData u);
addTheme(Theme t, UserData u){ tService.createTheme(t, u); }
getTheme(String name, UserData u){ tService.getTheme(name, u); }
hasThemes(String name, UserData u){ tService.hasTheme(name, u); }
}
今すぐThemeServiceはUserDataに密接に結合されています。要件がこれまでに変更とテーマが別のエンティティに属することができた場合は、ThemeCollectionは例えば、私は本当にThemeServiceからのコードの多くを再利用することはできませんし、今ThemeCollectionのもののためのより多くのコードが必要です。
public class ThemeService{
//...continued or in another ThemeService class...
createTheme(Theme t, ThemeCollection c);
getTheme(String name, ThemeCollection c);
hasTheme(String name, ThemeCollection c);
validateTheme(Theme t, ThemeCollection c);
}
public class ThemeCollectionService{
ThemeService tService;
getCollectionName(ThemeCollection c);
addTheme(Theme t, ThemeCollection c){ tService.createTheme(t, c); }
getTheme(String name, ThemeCollection c){ tService.getTheme(name, c); }
hasThemes(String name, ThemeCollection c){ tService.hasTheme(name, c); }
}
Iをそれは "Themeable"のようなものを実装する汎用パラメータを取るように誘惑されるでしょう。しかし、エンティティはインターフェイスを実装するだろうという。
public class ThemeService{
createTheme(Theme t, Themeable owner);
getTheme(String name, Themeable owner);
hasTheme(String name, Themeable owner);
validateTheme(Theme t, Themeable owner);
}
@Entity
public class UserData implements Themeable{
getUsername();
getThemes(); //From Themable
}
@Entity
public class ThemeCollection implements Themeable{
getUsername();
getThemes(); //From Themable
}
私はそのはず、私のエンティティクラスのビジネスロジックをしたくないので、私はテーマに対応インターフェイスで作成、取得、検証、などは含まれていませんうまくいけば、純粋なデータ構造(モデル内のビジネスロジックがロバートマーティンの「クリーンコード」によればうっすらで、私はいくつかの標準を守ろうとしています)です。
これをデカップリングするための標準的な方法、パターン、コンベンションなどがありますか?私は多かれ少なかれ「大丈夫」か、それともプロダクション環境でぶつかるのですか?私は "仕事を終わらせる"というコードから、モジュール化して再利用可能なコードに向かっています。だから、どんな助けと指針も大変ありがとうございます。
編集:「サービスが2つのエンティティに結合されているのはなぜですか?」
私は所有エンティティと所有エンティティを一緒に「ステッチ」する場所が必要です。例えば、UserDataのためcreateTheme:
public void createTheme(Theme t, UserData u){
entityManager.persist(t);
if(!hasTheme(t.name(), u){
u.getThemes().add(t);
entityManager.merge(u);
}
}
だから、この関数は、UserDataのに結合され、かつ任意の同様の「テーマの所有者は、」類似したコードを持っているでしょう。
サービスが2つのエンティティに結合されているのはなぜですか?あなたはこれの理由を明らかにするためにいくつかのコードを投稿できますか? –
@NiklasP質問の最後に短いスニペットを追加しました。 – GuitarStrum
これは疑問にはあまり答えません。本当に 'UserData'が本当に**が' Theme'を所有しているのであれば、なぜ新しいテーマを追加するには 'UserData'エンティティを更新する以外のことがありますか?あなたが言及した 'ステッチング'はおそらく 'UserDataService'で行われるべきです。 – crizzis