目錄
design pattern 以java 為例
要素
- 高階模組不應該依賴於低階模組。兩者都應該依賴於抽象。
- 抽象不應該依賴於細節。細節應該依賴於抽象。
範例
違反的例子
Notifiaction
這個class 直接把email 包在裡面做使用,未來如果要加簡訊或是其他傳訊方式就會無法解耦,屬於高階模組依賴於低階的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class EmailService { public void sendEmail(String message, String receiver) { System.out.println("Sending an email to " + receiver + ": " + message); } }
class Notification { private EmailService emailService;
public Notification() { this.emailService = new EmailService(); }
public void sendNotification(String message, String email) { emailService.sendEmail(message, email); } }
|
修正
1. 定義接口
1 2 3
| interface MessageService { void sendMessage(String message, String receiver); }
|
2. 低階模組實現抽象
1 2 3 4 5 6
| class EmailService implements MessageService { public void sendMessage(String message, String receiver) { System.out.println("Sending an email to " + receiver + ": " + message); } }
|
3. 高階模組依賴於抽象
1 2 3 4 5 6 7 8 9 10 11
| class Notification { private MessageService messageService;
public Notification(MessageService messageService) { this.messageService = messageService; }
public void sendNotification(String message, String receiver) { messageService.sendMessage(message, receiver); } }
|
4. 組裝應用
1 2 3 4 5 6 7
| class Application { public static void main(String[] args) { MessageService emailService = new EmailService(); Notification notification = new Notification(emailService); notification.sendNotification("Hello DIP!", "user@example.com"); } }
|
結果
遵循了依賴反轉原則,也使得系統更加靈活和可擴展。例如,如果未來我們需要通過SMS發送通知,我們只需創建一個新的 SMSService
類實現 MessageService
接口,並在應用組裝時傳遞給 Notification
類的實例,無需修改 Notification
的內部實現。