を投影し、私は多くの相互依存の部分でプロジェクトを持っている:が
myProject
- core
- core_web (depends on core)
- app1_core (depends on core)
- app1_web (depends on app1_core and core_web)
- app2_core (depends on core)
- app2_web (depends on app2_core and core_web)
私はcore
とcore_web
で定義された典型的なMVC片持ち:サービス、コントローラ、リポジトリ、JPAをエンティティなど
されるよう-app1
プロジェクトはすべて、このコアのものを使用しています - 私はいくつかの@Configuration
魔法で出て作業することができますapplication.properties
といくつかの特定の構成を除き、追加の作品はありません。しかし、フィールドとList
フィールドをエンティティに追加します。 DTO、工場、コントローラー、サービスなどは、デザインの観点からみれば、まるで不快感を感じる混乱のようなものになります。これを処理する、より良い、DRY-er、より良いベストプラクティスの方法があるのでしょうか?あるいは、エンティティにいくつかのフィールドを追加するだけで、ほぼすべてのクラスをコアコードから継承する必要がありますか? (簡潔さと素晴らしさのためにここにLombokを使用して)簡単な例として、ここではcore
から@Entity
です:
package com.example.core;
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "ACCOUNT")
@ToString(of = {"id", "emailAddress", "name"})
@EqualsAndHashCode
public class Account implements Serializable {
private static final long serialVersionUID = 1L;
@Embedded
private Address address;
@Id
@GenericGenerator(
name = "SEQ_ACCOUNT_ID",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
@Parameter(name = "sequence_name", value = "SEQ_ACCOUNT_ID"),
@Parameter(name = "initial_value", value = "1"),
@Parameter(name = "increment_size", value = "1")
}
)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ACCOUNT_ID")
@Column(name = "ACCOUNT_ID", updatable = false, nullable = false, unique = true)
private Long id;
@Column(name = "EMAIL", nullable = false, length = 200, unique = true)
private String emailAddress;
public void setEmailAddress(String emailAddress) {
this.emailAddress = StringUtils.lowerCase(emailAddress);
}
@JsonIgnore
@Column(name = "PASSWORD_HASH", nullable = false, length = 256)
private String passwordHash;
@Column(name = "NAME", nullable = false, length = 200)
private String name;
@Column(name = "PHONE", nullable = false, length = 30)
private String phoneNumber;
@Column(name = "URL")
private String url;
}
今、私はこの金額を期待しapp2
package com.example.app2;
@Data
@NoArgsConstructor
@Table(name = "ACCOUNT")
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Bride extends Account {
@Column(name = "WEDDING_DATE")
private Date weddingDate;
}
に余分なフィールドを追加仕事の。まともな、優雅な、重複しない、と私はエンティティの両方のクラスをスキャンしないように春に指示する限り、それはすべて良いです。それは退屈な取得を開始し、どこが、例えば、サービスコードの追加を開始するときされています。今、メイン質問
package com.example.core;
@Service
public class AccountService {
private AccountRepository accountRepository;
@Autowired
public AccountService(AccountRepository accountRepository) {
this.accountRepository = accountRepository;
}
/* the command object here would mirror Account, but contain some code
* to handle input validation and the like. I know I could just use the
* entity class, but I've been bitten by using entity classes as DTOs or
* command objects before, so I'd like to keep them separate.
*/
public Account createAccount(CreateAccountCommand createAccountCommand) {
Account account = new Account();
account.setEmailAddress(createAccountCommand.getEmailAddress());
account.setPasswordHash(createPasswordHash(createAccountCommand.getPassword()));
account.setName(createAccountCommand.getName());
account.setPhoneNumber(createAccountCommand.getPhoneNumber());
account.setUrl(createAccountCommand.getUrl());
}
}
:はどのように(読み:必要があります)か、私はBride
に余分なフィールドを扱うを? AccountService
に拡張されたBrideService
という新しいクラスを作成し、super.createAccount()
を呼び出しますか?だから私は今もその余分なフィールドを持つコマンドオブジェクトが必要ですか?バリデーターは余分なフィールドを処理する必要があるので、私はAccountValidator
クラスを継承していますか?あなたが見ることができるように、私は、この地味な継承されたクラスの滑りやすい斜面を取得し、ある時点でそれらを一般的に扱えるはずのすべてのクラスに1つまたは2つのフィールドのロジックを追加する目的にのみ役立ちます。つまり、それが多型の目的ですよね?だから、私はAccount
をどこにでも使って、サービスなどは "ちょうどいいですか?"この絡み合った混乱のどこかにアダプタのパターンがうまくいくのでしょうか?アドバイスを事前に感謝します。
驚くばかりの答えと私が探していたものとまったく同じです。ありがとうございました。 – Andy