【轉載自本科老師上課課件】
問題一:
在一個軟體的功能模組中,需要一種影像處理的功能。該影像處理的策略(如何處理)與影像的內容是相關的。如:衛星的執行圖片,使用策略A處理方式,如果是衛星內雲圖片,則需要策略B處理方式。隨時可向系統新增新的處理策略。處理時從GUI選單下選擇一種策略進行處理。 請使用Java設計出相應的程式。
【解決】
方法1:程式導向的傳統方式
定義一個大的函式:
void strategy(int selection)
{
if(selection==1){
//按第一種選擇的策略進行處理:處理程式碼
}
else if(selection==2){
//按第二種選擇的策略進行處理:處理程式碼
}
…
else if(selection==n){
//按第n種選擇的策略進行處理:處理程式碼
}
}
客戶端呼叫程式碼:
根據GUI下拉選單的選擇項,呼叫:strategy(n)
方法2:物件導向的傳統方式
定義一個類,包含所有的策略:
public class Strategy{
public static void strategy1()
{
//策略1的處理程式碼
}
public static void strategy2()
{
//策略2的處理程式碼
}
//…
public static void strategyn()
{
//策略n的處理程式碼
}
}
客戶端呼叫程式碼:
根據GUI下拉選單的選擇項,呼叫相應的策略程式碼: Strategy. strategyn()
方法3:介面的設計方案 !!!
(1)定義一個介面:Strategy
public interface Strategy{
public void strategy();//策略處理程式碼
}
(2)隨時新增新策略:就是隨時實現該介面!(不需要修改已打包封裝好的原始的類庫包)這是一種純增量式程式碼的修改新增
public class NewAddStrategy implement Strategy
{
public void strategy(){
//新策略的處理程式碼
}
}
(3)客戶端程式碼:針對介面進行軟體設計
public class Client
{
Strategy strategy;
//呼叫方式:
//strategy. strategy();
}
(4)關係圖
問題二:
手機等裝置中,對於如藍芽裝置,在整個系統中只需要一個物件表達它。如何控制系統,確保只生成一個物件呢?
【解決】
思路:
1)構造器隱藏起來。即private
2)定義唯一的一個private static 成員儲存它。
3)開放一個public static 方法,獲取唯一的那個物件。
設計結果----單例模式 !
public class BLDev
{
private static BLDev obj=new BLDev();
private void BLDev(){
//藍芽裝置初始代程式碼
}
public static BLDev getDefaultBLDev()
{
return obj;
}
}
//使用方法:在需要BLDev物件的地方:
BLDev bl=BLDev.getDefaultBLDev();
問題三:
有一個整點報時的服務,每當整點時,向需要整點報時服務的其它物件發出整點通知。整點報時服務在整個系統中只需要一個即可(不允許產生多個)。
【解決】
- 設計思考:服務者與需要服務的物件之間:
- 物件需要服務。如何表達這一點?
- 只有物件自己才能知道,它需不需要服務。故:讓物件自己向服務提供者表達:我需要服務。即:服務提供者應該提供一個手段,讓其它物件向它表達“我需要服務”。即:註冊。因而:void register(需要服務的物件)
- 物件不再需要服務。如何表達這一點?
- 只有物件自己才能知道,它不再需要服務。 故:讓物件自己向服務提供者表達:我不再需要服務了。 即:服務提供者應該提供一個手段,讓其它物件向它表達“我不再需要服務了”。即:刪除註冊。 因而:void unregister(不再需要服務的物件)
- 發出通知。如何設計?
- 當整點到時,服務應該向所有需要服務的那些物件,發出通知。 因此:服務應該有一個手段,向所有的註冊者發出通知。 因而:設計一個方法,通知這些物件。 void notifies()
- 物件怎樣得到通知,然後可處理相應邏輯。如何設計?
- 生活中,得到通知的方式:打電話+(通知內容)?EMAIL +(通知內容)?QQ +(通知內容)?.... 故:每一個要得到通知的物件,必須提供一個方法,由服務提供方去自動呼叫,並且傳入相應的通知內容。 如何保證:1)每一個要得到通知的物件,提供的方法,其名字、引數、返回值等保持一致?2)而且必須要提供此方法?(約束),否則得不到通知?
- 這引導我們自然而然地作出設計:這正是介面。
故:設計決策:設計出一個介面,只有實現該介面的類的物件,才能有資格得到通知【 因為:保證:1)每一個要得到通知的物件,提供的方法,其名字、引數、返回值等保持一致?2)而且必須要提供此方法?(約束),否則得不到通知?】 - 介面:TimeListener
方法: 用於得到通知
方法名:service
傳入引數:整點時間資料及其它資料(如:發生的上下文等)。
故:設計時,抽象出類:TimeEvent來表達它。
結果:void service(TimeEvent e)
- 整點報時服務規範化、標準化,適用更多的具有服務特性的物件。如何設計?
- 觀察發現:幾乎所有的服務都應該具有這樣的特性:註冊、解註冊、發出通知。而整點報時服務,也具有這個特性。 具有。。。特性,暗示我們:將這樣的特性抽象成:抽象類?還是介面?
- 還是介面
每一個服務應該具有的特性:
public interface Serviceable
{
void register(TimeListener tl);
void unregister(TimeListener tl);
void notifies();
} - 提供整點報時的Service自然具有Serviceable特性
故:
public class TimeService
implements Serviceable
{
//略
}
- 只能產生一個物件。如何設計?其它考慮。
- 分析:
1)構造器隱藏。
2)提供一個public static 方法,只能通過該方法,才能獲取該物件。 - 程式碼設計
-
public class TimeService implements TimeListener { //… private TimeService(){} private static TimeService ts=new TimeService(); public static TimeService getTimeService() { return ts; } }
- 分析:
- 物件需要服務。如何表達這一點?