2010-05-13 97 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(); 
    } 
}