Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
哪种软件设计模式最适合以下场景(C#)_C#_Architecture_Design Patterns_Device - Fatal编程技术网

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

哪种软件设计模式最适合以下场景(C#),c#,architecture,design-patterns,device,C#,Architecture,Design Patterns,Device,我有一个gps设备,可以记录数据,例如日期时间、纬度、经度 我有一个sdk,可以从设备读取数据。读取数据的方式: 命令包(基本上是结构中int值的组合)被发送到设备。 设备以固定大小的数据块(例如64字节)响应 根据发出的命令,我将返回不同的数据结构 例如 向设备发送命令1会返回类似 struct x { id int, name char[20] } 命令2返回以下结构的集合(基本上它归结为一个structs-y[12]数组) 然后我想将结构转换为类,并将数据保存到数据库中 封装整个过程

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

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

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

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

struct x
{
 id int,
 name char[20]
}
命令2返回以下结构的集合(基本上它归结为一个structs-y[12]数组)

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

封装整个过程的最佳方式是什么,最好使用一些已建立的设计模式

非常感谢
M

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


除此之外,我认为你可能需要研究一下模式。也许是模式

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

然后是一个用于发送和接收的类——如果您想真正解耦,命令知道如何序列化自身,或者另一个配对对象可以这样做

一些工厂对象将基于解析响应(可能还有上一次发送的请求/命令的知识)创建适当的响应类型对象

响应对象将结构响应作为参数

然后创建一个数据库/持久化对象,该对象知道如何告诉对象保存它们自己(或者将响应对象与持久化对象配对以实现更多的解耦)

也许有更好的方法可以做到这一点,但以上这些对我来说似乎是合理的,我在编写与医疗实验室设备通信的rs232应用程序时做了很多这方面的工作。

使用工厂

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

另一种方法是使用适配器。不只是读取结构中的每个字段并使用它来构造模型对象,您可以创建一个适配器对象,该对象包含结构并向代码的其余部分显示所需的接口。然后,您的工厂可以处理查询并返回经过调整的结构

我会避开装饰图案。这不是一个坏模式,但当您需要动态添加或删除行为时,它会更有用。在本例中,您没有提到动态执行此操作的必要性,因此Decorator的功能有些过火

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

@Ryan Elkins

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

顺便说一句,蒂姆的回答更符合我所做的


感谢您的回复

我以前遇到过这个问题,我使用接口和泛型进行了一些尝试,并成功地做到了:

// 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();
    }
} 
//调用者
公共课程
{
静态void Main(字符串[]参数)
{
设备cmd1=新设备();
S1=cmd1.ExecuteCommand(newcommand1());
Device cmd2=新设备();
S2=cmd2.ExecuteCommand(newcommand2());
}
}
//SDK
公共接口ICommand
{
T执行();
}
公共结构S1
{
公共int id;
}
公共结构S2
{
公共字符串名称;
}
公共类命令1:ICommand
{
公共S1执行()
{返回新的S1(){id=1};}
}
公共类命令2:ICommand
{
公共S2执行()
{返回新的S2(){name=“name”};}
}
//装置
公共类设备,其中T:ICommand
{
公共U执行命令(Cmdt对象)
{
返回cmdObject.Execute();
}
} 

所谓“封装整个过程”是指检测返回的内容并将其保存到数据库中吗?另外,为什么要将其转换为对象?在它进入数据库后,你还在用它做其他事情吗?
// 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();
    }
}