开发者

C# General Library Structure

开发者 https://www.devze.com 2023-04-11 05:29 出处:网络
I want to develop a library for communicating with a circuit via serial port. This circuit understands roughly 100 serial commands and returns a response string.

I want to develop a library for communicating with a circuit via serial port. This circuit understands roughly 100 serial commands and returns a response string.

The commands are divided into 3 categories (settings, environment, and outputs) so I would like to use properties or some other means to nest the categories and methods within the overall class. Instead of throwing all the command methods under a single class, what would be the recommended way to nest them? I want to avoid the following at all costs, it would just be a mess:

public class CircuitLib
{
   ...
   // Methods.
   public string SettingCommand1(string command) {...}
   ...
   public string SettingCommand30(string command) {...}

   public string EnvironmentCommand1(string command) {...}
   ...
   public string EnvironmentCommand30(string command) {...}

   public string OutputCommand1(string command) {...}
   ...
   public string OutputCommand30(string command) {...}
}

It would be nice to be able to use properties to get to the specified category:

circuitLibInstance.GetSettingsProperty.OneOfTheSettingsMethods开发者_如何学Go(stringCommand);

Any guidance would be GREATLY appreciated.

Thanks Everyone!


Well you could have:

public class Circuit
{
    // Initialize these in the constructor
    private readonly SettingCommands settings;
    private readonly EnvironmentCommands environment;
    private readonly OutputCommands output;

    public SettingCommands Settings { get { return settings; } }
    public EnvironmentCommands Environment { get { return environment; } }
    public OutputCommands Output { get { return output; } }
}

public class SettingCommands
{
    public string Foo(string command) { ... }
}

Then:

string result = instance.Settings.Foo("hello");

Is that what you were after?

Of course if all your command methods actually have the same structure, you might potentially want an enum, for example:

public enum SettingCommand { Foo, Bar, Baz }
public enum EnvironmentCommand { Alice, Bob, Charlie }
public enum OutputCommand { Ender, Bean, Alai }

then:

public class Circuit
{
    public string Execute(SettingCommand command, string data) { ... }
    public string Execute(EnvironmentCommand command, string data) { ... }
    public string Execute(OutputCommand command, string data) { ... }
}

and use as:

string result = instance.Execute(SettingCommand.Foo, "data");


I'm guessing the command string has to be formatted in a very specific way. If so I would abstract that knowledge so that it's encapsulated within your CircuitLib. So I would probably have something like:

public class CircuitLib {
    public string SettingCommand1(int a, bool b, string c) {}
    public string SettingCommand2(bool a, double b) {}
    public string EnvironmentCommand2(string a, DateTime b) {}
    ...
}

The the individual methods are responsible for accepting the strongly typed data and creating the propertly formatted strings that get sent to the device. In this case I don't see any problem with having a class with 100 methods as it is encapsulating a device with a very procedural interface that can understand 100 methods.

Alternatively, if you really want the interface you suggested you could do it easily enough like so:

public class CircuitLib {
    public SettingCircuitLib Settings {get; set;}
    public EnvironmentCircuitLib Environment {get; set;}
}

public class SettingCircuitLib {
    public string SettingCommand1(string command) {}
    public string SettingCommand2(string command) {}
}

then you'd just call it like so:

CircuitLibInstance.Settings.SettingCommand1(cmd);
CircuitLibInstance.Environment.EnvironmentCommand1(cmd);


I think I might approach it a little more 'fluent' like:

public class CircuitLib
{
    public CircuitSetting Setting { get; }
    public CircuitEnvironment Environment { get; }
    public CircuitOutput Command { get; }
}

//Obviously you need one for each type above
public class CircuitSetting
{
    CircutSettingCommand1 Command1 { get; }
    CircutSettingCommand30 Command30 { get; }
}
public class CircutSettingCommand1 
{
    Send(string command);
}

However you build the class structure, rigid like above, or some interfaces, etc, the goal is still the same. Be able to write client code something like the following:

using(CircuitLib lib = new CircuitLib(...))
{
    lib.Setting.Command1.Send("Hello World");
}

This allows a user fewer choices to start with as the navigate down the structure.


I would create your library as a static class that contains three instance classes like:

public class Settings 
{
     public string SettingCommand1(string command) {...}
     ...
     public string SettingCommand30(string command) {...}
}
public class Environment 
{
     public string EnvironmentCommand1(string command) {...}
     ...
     public string EnvironmentCommand30(string command) {...}
}
public class Output
{
     public string OutputCommand1(string command) {...}
     ...
     public string OutputCommand30(string command) {...}
}    
public static class CircuitLib
{
     public static Settings Settings = new Settings ();
     public static Environment Environment = new Environment ();
     public static Output Output  = new Output();
}

Then you can use it like:

CircuitLib.Settings.SettingCommand1("input");
CircuitLib.Environment.EnvironmentCommand30("input");
0

精彩评论

暂无评论...
验证码 换一张
取 消