2010-05-13 82 views
3

我有一個gps設備可以記錄數據,例如:日期時間,經度,緯度什麼軟件設計模式最適合以下場景(C#)

我有一個sdk從設備讀取數據。數據讀取方式:

命令包(基本上是結構體中的int值的組合)被髮送到設備。該設備以固定大小塊的數據響應,例如, 64字節

根據發出的命令,我將返回不同的數據結構 發送命令1到設備返回一個結構象

struct x 
{ 
id int, 
name char[20] 
} 

命令2返回以下結構的集合(基本上它歸結爲結構的數組 - Y [12])

struct y 
{ 
date datetime, 
lat decimal, 
lon decimal 
} 

然後,我會想要將結構轉換爲類並將數據保存到數據庫。

什麼是最好的方式來封裝整個過程,最好使用一些既定的設計模式?

非常感謝 中號

+0

通過「封裝的整個過程」你的意思檢測什麼是返回並保存到數據庫? – 2010-05-13 15:20:00

+0

另外,你爲什麼要將它轉換爲一個對象?在進入數據庫之後,你還在做其他事情嗎? – 2010-05-13 15:26:06

回答

0

我會從命令和響應的基類開始,每個特定的命令或響應都源自這些基類。

然後是一個發送和接收類 - 無論命令知道如何序列化自己或另一個配對的對象可以做到這一點,如果你想真正解耦的東西。

一些工廠對象將創建基於解析響應(可能與上次發送的請求/命令的知識一起)

響應對象構造函數取結構響應作爲參數的正確響應類型的對象。

然後你讓一個數據庫/持久性對象,它知道如何告訴對象自救(或者你有響應對象的配對持久性去耦對象)

可能有更好的方法來做到這一點,但上述對我來說似乎是合理的,而且我爲編寫與醫學實驗室設備交談的rs232應用程序所做的很多工作都是合理的。

0

不知道這是否可以通過一個單一的模式覆蓋。實際上,我認爲選擇設計模式並實施它並不是一個好方法。

除此之外,我想你可能想看看Chain of Responsibility模式。也許Decorator模式。

1

使用工廠。

發送查詢到工廠,該工廠從庫中獲取結構。然後讓它讀取結構並將其放入任何你想要的對象。工廠然後返回該對象。

另一種方法是使用適配器。您可以創建一個包含結構的適配器對象,並向代碼的其餘部分顯示所需的接口,而不是僅僅讀取結構中的每個字段並使用它來構造模型對象。然後你的工廠可以處理查詢並返回一個適應的結構。

我會迴避裝飾模式。這不是一個不好的模式,但當你需要動態添加或刪除行爲時,它更有用。在這種情況下,你沒有提到需要動態地做這件事,所以Decorator是矯枉過正的。

在數據庫方面,一個簡單的數據訪問對象(DAO)將允許您將模型對象傳遞給其中一個CRUD方法。這不是最優雅的解決方案,但它聽起來像你不需要JDO類型解決方案的額外優雅。

0

@Ryan埃爾金

所謂「封裝整個過程」,我的意思是從該設備發送一個命令到設備,讀取數據(我知道將被返回的結構定義)的過程中, 然後使用一個定義類似於struct的類將其轉換爲對象(我將稍後使用相同的類從db讀取記錄) 並將結果保存到db。

Btw蒂姆的答案更符合我在做什麼。

感謝您的答覆

0

我這個問題之前,我沒有使用接口和泛型一個小黑客,設法做到這一點:

// CALLER 
public class Program 
{ 
    static void Main(string[] args) 
    { 
     Device<Command1, S1> cmd1 = new Device<Command1, S1>(); 
     S1 s1 = cmd1.ExecuteCommand(new Command1()); 

     Device<Command2, S2> cmd2 = new Device<Command2, S2>(); 
     S2 s2 = cmd2.ExecuteCommand(new Command2()); 
    } 
} 

// SDK 
public interface ICommand<T> 
{ 
    T Execute(); 
} 

public struct S1 
{ 
    public int id; 
} 

public struct S2 
{ 
    public string name; 
} 

public class Command1 : ICommand<S1> 
{ 
    public S1 Execute() 
    { return new S1() { id = 1 }; } 
} 

public class Command2 : ICommand<S2> 
{ 
    public S2 Execute() 
    { return new S2() { name = "name" }; } 
} 

// DEVICE 
public class Device<T, U> where T : ICommand<U> 
{ 
    public U ExecuteCommand(T cmdObject) 
    { 
     return cmdObject.Execute(); 
    } 
}