Re: Designfrage in C#
- From: "Günter Prossliner" <g.prossliner/gmx/at>
- Date: Wed, 7 Dec 2005 13:46:42 +0100
Hallo Peter!
> Ich möchte irgendwie den Befehlssatz des Gerätes in einer
> Objektstruktur kapseln,
> so das es möglich wird später ohne großen Programieraufwand neue
> Befehle für ein Gerät hinzuzufügen und das die einzelnen
> Befehlsstrings vom restlichen Programmcode entkapselt sind und da
> nicht auftauchen.
Was aus dem Text nicht hervorgeht ist ob Du auch verschiedene Geräte hast
die den gleichen Command unterschiedlich händeln.
Sonst wäre eigentlich ganz einfach folgendes möglich:
class CommandBase{
protected void WriteCommand(string command) ...
protected string ReadCommand(int len) ...
}
namespace Commands{
// command without return a result
class Command1 : CommandBase{
public void Send(){
WriteCommand("CMD1");
}
}
// command returning a result
class Command2 : CommandBase{
public string Send(){
WriteCommand("CMD2);
string ret = ReadCommand(2);
}
}
// command with parameters
class Command3 : CommandBase{
public void Send(int i){
WriteCommand("CMD3 " + i.ToString());
}
}
}
Anwendung:
void foo(){
new Commands.Command1().Send();
string s = new Commands.Command2().Send();
new Commands.Command3.Send(1);
}
Ein Nachteil an dieser Archtiktur ist dass das Objekt inkl. Verbindung immer
neu genieriert werden muss. Sollte zu der Erstellung eine CommandBase -
Objektes eine Reihe von Parametern mitgegeben werden müssen ist es ggf.
besser die zugrundlegende Verbindung inkl. Senden und Empfangen in eine
eigene Klasse zu packen (am besten als ein von Stream abgeleitete Klasse),
und die Commands dann mit einem zugrundeliegenden Stream zu erstellen. Ein
weiterer Vorteil ist dass Du dann z.B. zu Debugging - Zwecken z.B. einen
FileStream nehmen kannst und dadurch dann alle Ausgaben in eine Datei
umleitest.
Der Aufbau wäre dann z.B.:
class CommandStream : Stream {
public CommandStream(string port, int baudrate, ...) {...}
}
abstract class CommandBase{
protected Stream CommandStream;
Encoding _encoding = System.Text.Encoding.Default;
protected CommandBase(Stream stream){
CommandStream = stream;
}
protected void WriteCommand(string cmd){
byte[] data = _encoding.GetBytes(cmd);
CommandStream.Write(data, 0, data.Length);
}
protected string ReadCommand(int len){
byte[] data = new byte[len];
CommandStream.Read(data, 0, len);
return _encoding.GetString(data);
}
}
namespace Commands{
class Command1 : CommandBase {
public Command1(Stream s) : base(s) {}
public void Send(){
WriteCommand("CMD1");
}
}
class Command2 : ComandBase {
public Command2(Stream s) : base(s) {}
public string Send(int i){
WriteCommand("CMD2 " + i.ToString());
return ReadCommand(5);
}
}
}
Anwendung:
void foo(){
CommandStream s = new CommandStream("COM1", 9600, ...);
Commands.Command1 cmd1 = new Commands.Command1(s);
cmd1.Send();
Commands.Command2 cmd2 = new Commands.Command2(s);
string r = cmd2.Send(1);
}
Was die Übergabe bzw. das Empfangen von Strings angeht würde ich mir auch
noch überlegen ggf. aus byte[] umzusteigen, ausser Du hast wirklich immer
nur Strings bzw. andere Datentype in deren String - Repräsenation, und das
Encoding ist definiert und immer das gleiche.
Beide Patterns gehen davon aus, dass die Send (bzw. Execute) Methode nicht
abstrahiert werden muss um diese ggf. z.B: über ein Script auszuführen.
Sollte das notwendig sein musst Du für die Parameter bzw. die Return - Daten
gemeinsame Basisklasse verwenden; diese kann aber z.B. auch ein Xml sein.
.
- Prev by Date: Datagrid löschen?
- Next by Date: Re: suche in dataview
- Previous by thread: Re: Designfrage in C#
- Next by thread: Re: Designfrage in C#
- Index(es):
Relevant Pages
|