什么软件设计模式最适合以下场景(C#)

时间:2010-05-13 15:03:52

标签: c# architecture design-patterns device

我有一个记录数据的gps设备,例如日期时间,纬度,经度

我有一个从设备读取数据的sdk。读取数据的方式:

命令包(基本上是结构中int值的组合)被发送到设备。 设备以固定大小的块响应数据,例如64字节

根据发出的命令,我将返回不同的数据结构 例如 将命令1发送到设备会返回类似

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

命令2返回以下结构的集合(基本上它归结为结构数组 - y [12])

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

然后我想将结构转换为类并将数据保存到数据库中。

封装整个过程的最佳方法是什么,最好是使用一些既定的设计模式?

非常感谢 中号

5 个答案:

答案 0 :(得分:1)

使用工厂。

将查询发送到工厂,工厂从库中获取结构。然后让它读取结构并将其放入您想要的任何对象中。然后工厂返回对象。

另一种方法是使用适配器。您可以创建一个包含结构的适配器对象,并为其余代码提供所需的接口,而不是仅仅读取结构中的每个字段并使用它来构建模型对象。然后,您的工厂可以处理查询并返回适应的结构。

我不喜欢装饰者的模式。这不是一个糟糕的模式,但是当您需要动态添加或删除行为时,它会更有用。在这种情况下,您没有提到动态执行此操作的必要性,因此Decorator过度。

在数据库端,一个简单的数据访问对象(DAO)允许您将模型对象传递给其中一个CRUD方法。它不是最优雅的解决方案,但听起来您不需要JDO类型解决方案的额外优雅。

答案 1 :(得分:0)

不确定这是否可以由单一模式覆盖。实际上,我认为选择设计模式然后实现它并不是一个好方法。

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

答案 2 :(得分:0)

我将从命令和响应的基类开始,每个特定的命令或响应都来自那些。

然后是一个发送和接收的类 - 如果你想真正解耦,那么命令知道如何序列化自己或另一个配对对象可以做到这一点。

某些工厂对象会根据解析响应创建正确的响应类型对象(可能还有上次发送的请求/命令的知识)

响应对象ctor将struct响应作为参数。

然后创建一个知道如何告诉对象自己保存的数据库/持久化对象(或者你有一个响应对象与持久性对象配对以进行更多的解耦)

可能有更好的方法可以做到这一点,但上述内容对我来说似乎是合理的,而且我为写一个与医学实验室设备交谈的rs232应用程序做了很多。

答案 3 :(得分:0)

@Ryan Elkins

通过“封装整个过程”,我指的是向设备发送命令,从设备读取数据的过程(我知道将返回的结构定义), 然后使用类似于struct的类将其转换为对象(稍后我将使用相同的类来读取db中的记录) 并将结果保存到db。

顺便提一下蒂姆的回答更符合我的目的。

感谢您的回复

答案 4 :(得分:0)

之前我遇到过这个问题,我做了一些使用接口和泛型的hack并设法做到了:

// 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();
    }
}