問題主要是一個設計問題(與ddd有點相關)。對不起,關於這個人爲的例子:從同一基類的域類中調用不同的服務
假設,你有(域)類表示不同類型的水果:蘋果,櫻桃等。現在假設你必須實施一些壓制果汁的行爲。呼叫者應該能夠在不知道他得到哪個特定水果的情況下調用擠壓。
我應該把這種行爲放在哪裏?
當然,一個可以定義一個水果接口/基類的功能
Fruit#squeeze()
,並讓所有子類實現自己的行爲。 現在主叫方可以簡單地做這樣的事情:
Fruit f = new Cherry();
f.squeeze();
但如果擠不那麼簡單,涉及到更復雜的行爲就像調用不同的外部服務,爲每一個水果不同的人喜歡
應該做什麼AppleJuicerService#squeeze(Apple a)
和
CherryJuicerService#squeeze(Cherry c)
?從域類調用服務感覺不對。
我讀過關於雙調度模式,似乎不適合在這裏,因爲每個子類都需要不同的服務。
我的問題是:在這裏可以做些什麼來獲得「乾淨」的設計?
編輯:
感謝您的答案爲止。我會盡量澄清這個問題。我將嘗試給出另一個希望較少人爲的問題,例如我試圖在此處陳述的問題:
考慮允許將其內容顯示爲字符串的消息基類。
interface Message {
String showContent();
}
現在假設我們有不同類型的消息等的EMailMessage:
class EMailMessage implements Message {
//some specific parameters for email
private EmailAddress recipientEmail;
public String showContent() {
//here the content would be converted to string
return "the content of an EMail"
}
}
另一種類型的將是一個SMSMessage:
class SMSMessage implement SMSMessage {
//some specific parameters for SMS
private TelNumber recepientTelephoneNumber;
public String showContent() {
//here the content would be converted to string
return "the content of a SMS"
}
}
另外假設,消息被建模爲實體,並且因此可以保存在數據庫中。儘管在技術上很有意思,但假設像Spring這樣的一些依賴注入框架被用來注入依賴關係。
類似於水果的例子,考慮我們必須實現發送消息給收件人的send()行爲。此外,假設發送電子郵件涉及與SMS不同的邏輯。現在,問題是:應該在哪裏發送發送消息的邏輯?
通常我會選擇創建一個用於發送SMS的服務,例如將封裝例如SMS服務提供商的API。此外,我會創建另一個服務來封裝發送電子郵件。
interface SendMessageService<T extends Message> {
void send(T message);
}
class SendEmailService extends SendMessageService<EMailMessage> {
public void send(EMailMessage message) {
//send the EMail
}
}
class SendSMSService extends SendMessageService<SMSMessage> {
public void send(SMSMessage message) {
//send the SMS
}
}
這種方法的缺點是,你不能沒有確定它的具體子類,即像下面發送一條消息不能直接
List<Message> messages = //Messages of different types
SendMessageService service = //???
for (Message m : messages) {
service.send(m);
}
當然人們可以創建服務創建工廠根據消息的具體類型。但是這有點意味着克隆Message的繼承層次結構。有沒有更好的方法來達到預期的效果?或者我錯過了什麼?或者,以某種方式將服務注入實體會更好嗎?
也許這個例子在這裏做得太過分了 - Fruit#squeeze()有一個void返回類型,它對Fruit有什麼作用? –
+1如果您不解釋「擠壓」可能代表什麼以及爲什麼首先需要服務,我們無法提供一個好的答案。 (順便說一句,從一個實體中調用域服務是完全合法的,即使你會更頻繁地看到它) – guillaume31
@ guillaume31我試圖編輯問題以進一步解釋問題 – John