I'm currently working on a simple Client/Server model which sends packets within TCP packets (like HTTP) and the commands are basically ints (the first 4 bytes of each packet) and I'd like to work out an efficient way of how to process these commands.
The most obvious answer would be to write thousands of if's or do one huge switch statement with thousand cases, but isn't there any better way?
I'd like to create an array of events and then just raise the corresponding index so each int refers to one event which is named (such as MessageReceived). I'd also save time I think, so how could I work this out?
EDIT: The Server handles multiple connections, one for each client that is connected, so creating seperate connections for each command(s) isn't that useful in my case.
Sound like a job for enums!
enum YourEnum
{
DoThis,
DoThat
}
YourEnum foo = (YourEnum)yourInt;
Visual studio can even create your entire switch statement using the built in snippets and your code becomes very readable.
switch(foo)
becomes
switch(foo)
{
case YourEnum.DoThis:
break;
case YourEnum.DoThat:
break;
default:
break;
}
Update 1
This is a little scary from a maintainability point of view, but if you created a class like:
public class ActionProcessor
{
public void Process(int yourInt)
{
var methods = this.GetType().GetMethods();
if (methods.Length > yourInt)
{
methods[yourInt].Invoke(this, null);
}
}
public DoThis()
{
}
public DoThat()
{
}
or a little nicer but harder to maintain:
[AttributeUsageAttribute(AttributeTargets.Method,
Inherited = false,
AllowMultiple = false)]
public sealed class AutoActionAttribute : Attribute
{
public AutoActionAttibute(int methodID)
{
this.MethodID = methodID;
}
public int MethodID { get; set; }
}
public class ActionProcessor
{
public void Process(int yourInt)
{
var method = this.GetType().GetMethods()
.Where(x => x.GetCustomAttribute(typeof(AutoActionAttribute),
false) != null
&& x.GetCustomAttribute(typeof(AutoActionAttribute),
false).MethodID == yourInt)
.FirstOrDefault();
if (method != null)
{
method.Invoke(this, null);
}
}
[AutoAction(1)]
public DoThis()
{
}
[AutoAction(2)]
public DoThat()
{
}
}
Update 2 (Coding what I think Josh C. was talking about)
// Handles all incoming requests.
public class GenericProcessor
{
public delegate void ActionEventHandler(object sender, ActionEventArgs e);
public event ActionEventHandler ActionEvent;
public ProcessAction(int actionValue)
{
if (this.ActionEvent != null)
{
this.ActionEvent(this, new ActionEventArgs(actionValue));
}
}
}
// Definition of values for request
// Extend as needed
public class ActionEventArgs : EventArgs
{
public ActionEventArgs(int actionValue)
{
this.ActionValue = actionValue;
}
public virtual int ActionValue { get; private set; }
}
This you create the SomeActionProcessor that is responsible for some value:
// Handles a specific (or multiple) requests
public class SomeActionProcessor
{
public void HandleActionEvent(object sender, ActionEventArgs e)
{
if (e.ActionValue == 1)
{
this.HandleAction();
}
}
private void HandleAction()
{
}
}
Then create the classes and wire them up:
GenericProcessor gp = new GenericProcessor();
SomeActionProcessor sap = new SomeActionProcessor();
gp.ActionEvent += sap.HandleActionEvent;
The fire away and sending the generic processor requests:
gp.ProcessAction(1);
You could possibly implement a publisher-subscriber model. Instead of having one listener, you would have many. Each listener would listen for at least one command. Then you can split your switch across multiple classes.
Related
because of this post I create a new question to make my probleme more clear. I have a class with a next class member, so there will be a daisy chain of class instances. A function in my class calls another member function or all instances in the chain.
c ++ has a resonable solution for this problem. In C# I tried it with a delegate. I made a short program to show what I mean.
class Program {
static void Main(string[] args)
{
DaisyChain TestClass = new DaisyChain(1);
TestClass.AddClass(new DaisyChain(2));
TestClass.AllprintID();
}
}
class DaisyChain {
private int ClassID;
private DaisyChain NextClass;
public DaisyChain(int ID) {ClassID = ID; }
public void AddClass(DaisyChain newClass) {
if (NextClass == null) {
NextClass = newClass;
} else {
NextClass.AddClass(newClass);
}
}
public void AllprintID() {
DoForEach(this.printID);
}
public delegate void doFunc();
public void DoForEach (doFunc aMemberFunc) {
aMemberFunc();
if (NextClass != null) {
NextClass.DoForEach(aMemberFunc);
}
}
public void printID() {
Console.WriteLine(ClassID);
}
};
This example do not work correct, because the class instance is not part of the function call.
I can add a class argumnet to my member function and chang the delegate,
public void printID(DaisyChain me) {
Console.WriteLine(me.ClassID);
}
but then the function will be static and no longer usable in the normal way.
I would be happy if ther another solution.
The delegate type should have an extra argument, since you want to call printID on different objects. You can either add one to doFunc, or just use the built in Action<T> delegate type.
public void DoForEach (Action<DaisyChain> aMemberFunc) {
aMemberFunc(this);
if (NextClass != null) {
NextClass.DoForEach(aMemberFunc);
}
}
When calling DoForEach, you can either pass a lambda expression:
public void AllprintID() {
DoForEach(x => x.printID());
}
Or if you really like the method group syntax for some reason, write a local function printID:
public void AllprintID() {
void PrintID(DaisyChain chain) {
chain.PrintID();
}
DoForEach(PrintID);
}
// method names should start with a capital letter :)
public void PrintID() {
Console.WriteLine(ClassID);
}
Other code can still call PrintID as usual - code outside AllprintID won't even notice the local function.
You are trying to reinvent the wheel. Check LinkedList and LinkedListNode in the documentation. Here is an example to get you on the way:
var daisyChain = new DaisyChain();
daisyChain.Add(1);
daisyChain.Add(2);
class DaisyChain: LinkedList<DaisyChainLink>
{
public void Add(int id) => AddLast(new LinkedListNode<DaisyChainLink>(new DaisyChainLink(id)));
public void Print()
{
var link = this.First;
link?.Value.Print();
while (null != link?.Next)
{
link = link.Next;
link?.Value.Print();
}
}
}
class DaisyChainLink
{
public DaisyChainLink(int id)
{
Id = id;
}
public int Id { get; }
public void Print() => Console.WriteLine(Id);
}
I have the following use case for a factory safety system. Currently designing the system as console application.
- A Machine's speed can be increased or decreased using human input - i or d
- when the speed is increased above 50, there is an alarm raised
- There is a safety lock in the machine which can be locked or unlocked again by human input - l or u
- If the speed of the machine is increased by 10 and safety lock is not locked, then there is an alarm raised
I have implemented the system, however, the system is not scallable. Tomorrow if another safety system introduced, then looks like I need to go back to the existing class and modify.
Implementing open close principle looks to be difficult as functionality like speed increase/decrease (ISpeedController) and machine lock/unlock (ISafetyLock) does not share a common interface.
public interface ISpeedController
{
void Increase();
void Decrease();
}
public interface ISafetyLock
{
void Lock();
void UnLock();
}
Moreover, there is an event speed change, which fires whenever speed is changed to raise an alarm. That makes things even more complicated.
Can you help me how the system can be designed so that we can seamlessly add new safety measures in future without impacting the current code?
Thanks.
Well, you just need to go with convention over configuration approach.
For example, you can define a common interface with registration:
using System;
using System.Linq;
public class Program
{
public static void Main()
{
var handlerType = typeof(IHandleKey);
var classes = typeof(Program).Assembly // you can get them however you want
.GetTypes()
.Where(p => handlerType.IsAssignableFrom(p) && p.IsClass)
.Select(t => (IHandleKey)Activator.CreateInstance(t)) // or use IoC to resolve them...
.ToArray();
while(true) {
var key = Console.ReadLine(); // or however you get your input
var handler = classes.FirstOrDefault(x => x.Key == key);
if (handler == null) {
Console.WriteLine("Couldn't find a handler for " + key);
} else {
handler.Handle();
}
}
}
}
public interface IHandleKey
{
String Key { get; }
void Handle();
}
public class Banana : IHandleKey
{
public String Key { get { return "u"; } }
public void Handle()
{
Console.WriteLine("I did banana work");
}
}
This way if you need to develop a new feature, all you need to add is one class that contains information about valid key and the implementation logic.
Likewise, if you don't want to have the instances ready to handle the command, you can split this and have an attribute describing the key on the type, like so:
using System;
using System.Linq;
public class Program
{
public static void Main()
{
var handlerType = typeof(IHandleKey);
var classes = typeof(Program).Assembly
.GetTypes()
.Where(p => handlerType.IsAssignableFrom(p) && p.IsClass && p.GetCustomAttributes(typeof(KeyHandlerAttribute), false).Count() > 0) // note we're checking for attribute here. This can be optimised.
.ToArray();
while(true) {
var key = Console.ReadLine(); // or however you get your input
var concreteType = classes.FirstOrDefault(x => ((KeyHandlerAttribute)(x.GetCustomAttributes(typeof(KeyHandlerAttribute), false).First())).Key == key);
if (concreteType == null) {
Console.WriteLine("Couldn't find a handler for " + key);
} else {
var handler = (IHandleKey)Activator.CreateInstance(concreteType); // or use IoC to resolve them...
handler.Handle();
}
}
}
}
public interface IHandleKey
{
void Handle();
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class KeyHandlerAttribute: Attribute
{
public String Key { get; set; }
}
[KeyHandler(Key = "u")]
public class Banana : IHandleKey
{
public void Handle()
{
Console.WriteLine("I did banana work");
}
}
Update Here's the updated program listing using the second variant and implementing shared state and event-based communication.
To be honest, I find this rather trivial, so feel free to ask any questions as i'm not sure what might appear more confusing and what not...
using System;
using System.Linq;
using System.Collections.Generic;
namespace Whatever
{
public class Program
{
public static void Main()
{
// This part belongs to IoC as a Singleton
var state = new State();
// This part belongs to IoC as scoped services
var handlerType = typeof(IHandleKey);
var dict = new Dictionary<String, Object>();
foreach (var type in typeof(Program).Assembly
.GetTypes()
.Where(p => handlerType.IsAssignableFrom(p) && p.IsClass))
{
var attributes = type.GetCustomAttributes(typeof(KeyHandlerAttribute), false);
if (attributes.Any())
{
var attribute = (KeyHandlerAttribute)attributes.First();
var handlr = (IHandleKey)Activator.CreateInstance(type);
handlr.RegisterEvent(state);
dict.Add(attribute.Key, handlr);
}
}
// Main routine here
while (true)
{
var key = Console.ReadLine(); // or however you get your input
var handler = dict.ContainsKey(key) ? (IHandleKey)dict[key] : null;
if (handler == null)
{
Console.WriteLine("Couldn't find a handler for " + key);
}
else
{
handler.Handle();
}
}
}
}
// This class allows us to share state.
public class State : ISharedState
{
// As required by the question, this is an event.
public event EventHandler StateChanged;
public void RaiseStateChange(object sender)
{
this.StateChanged.Invoke(sender, new EventArgs());
}
}
// This makes our Handlers unit testable.
public interface ISharedState
{
event EventHandler StateChanged;
void RaiseStateChange(object sender);
}
// Familiar interface -> note how we have a 'register event' method now.
// We could instead just use a constructor on the HandlerBase. This is really dealer's choice now.
public interface IHandleKey
{
void Handle();
void RegisterEvent(ISharedState state);
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class KeyHandlerAttribute : Attribute
{
public String Key { get; set; }
}
// To avoid boilerplate in our handlers for registering/unregistering events we have a base handler class now.
public abstract class HandlerBase: IHandleKey
{
protected ISharedState _state;
public abstract void Handle();
public void RegisterEvent(ISharedState state)
{
this._state = state;
this._state.StateChanged += OnStateChanged;
}
public abstract void OnStateChanged(object sender, EventArgs e);
~HandlerBase()
{
this._state.StateChanged -= OnStateChanged;
}
}
// Actual handlers...
[KeyHandler(Key = "u")]
public class Banana : HandlerBase
{
public override void Handle()
{
Console.WriteLine("I did banana work");
this._state.RaiseStateChange(this);
}
public override void OnStateChanged(object sender, EventArgs e)
{
if (sender != this) // optional, in case we don't want to do this for self-raised changes
{
Console.WriteLine("State changed inside Banana handler");
}
}
}
[KeyHandler(Key = "c")]
public class Cheese : HandlerBase
{
public override void Handle()
{
Console.WriteLine("I did cheese work");
this._state.RaiseStateChange(this);
}
public override void OnStateChanged(object sender, EventArgs e)
{
if (sender != this) // optional, in case we don't want to do this for self-raised changes
{
Console.WriteLine("State changed inside cheese handler");
}
}
}
}
I have an object that only initializes itself with barebones data when constructed (fast), and loads itself for real (slow) when first accessed. The idea is that I'm creating a lot of these barebones objects at startup and hash them into a map, then fully load each object whenever it is individually accessed for the first time. The problem is that I cannot guarantee how clients will interact with this object, there are multiple public methods that might be invoked.
Is there a good pattern to support this kind of situation? The obvious (and my current) solution is to track state with an internal bool, check against that bool in every function that might be invoked, and load that way. But that requires code duplication of that behavior across all public functions, and is vulnerable to errors.
I can imagine a single point-of-entry method that then dishes out behaviors based on a client request type etc., but before I go consider going down that road I want to see if there's a commonly accepted approach/pattern that I might not be aware of. I'm doing this in C#, but any insight is appreciated.
If I understood what you want to achieve, you are looking for the Proxy Design Pattern, more specifically, a virtual Proxy.
Refer to http://www.dofactory.com/net/proxy-design-pattern
A small example would be something like:
public abstract class IObjectProvider
{
public abstract IObjectProvider Object{get;}
public abstract void doStuff();
}
public class RealObject : IObjectProvider
{
public RealObject()
{
//Do very complicated and time taking stuff;
}
public override IObjectProvider Object
{
get { return this; }
}
public override void doStuff()
{
//do this stuff that these objects normally do
}
}
public class ObjectProxy : IObjectProvider
{
private IObjectProvider objectInstance = null;
public override IObjectProvider Object
{
get
{
if (objectInstance == null)
objectInstance = new RealObject();
return objectInstance;
}
}
public override void doStuff()
{
if(objectInstance!=null)
objectInstance.doStuff();
}
}
public class SkeletonClass
{
public IObjectProvider Proxy1 = new ObjectProxy();
public IObjectProvider Proxy2 = new ObjectProxy();
}
static void Main(String[] args)
{
//Objects Not Loaded
SkeletonClass skeleton = new SkeletonClass();
//Proxy1 loads object1 on demand
skeleton.Proxy1.Object.doStuff();
//Proxy2 not loaded object2 until someone needs it
}
Here's an example of dynamic proxy approach.
using System;
using System.Diagnostics;
using Castle.DynamicProxy; //Remember to include a reference, too. It's nugettable package is Castle.Core
namespace ConsoleApp
{
public class ActualClass
{
//Have static instances of two below for performance
private static ProxyGenerator pg = new ProxyGenerator();
private static ActualClassInterceptor interceptor = new ActualClassInterceptor();
//This is how we get ActualClass items that are wrapped in the Dynamic Proxy
public static ActualClass getActualClassInstance()
{
ActualClass instance = new ActualClass();
return pg.CreateClassProxyWithTarget<ActualClass>(instance, interceptor);
}
//Tracking whether init has been called
private bool initialized = false;
//Will be used as evidence of true initialization, i.e. no longer null
private int? someValue = null;
public void Initialize()
{
if (!initialized)
{
//do some initialization here.
someValue = -1; //Will only get set to non-null if we've run this line.
initialized = true;
}
}
//Any methods you want to intercept need to be virtual!
public virtual int replaceValue(int value)
{
//below will blow up, if someValue has not been set to -1 via Initialize();
int oldValue = someValue.Value;
someValue = value;
return oldValue;
}
//block off constructor from public to enforce use of getActualClassInstance
protected ActualClass() { }
}
public class ActualClassInterceptor : ActualClass, IInterceptor
{
public void Intercept(IInvocation invocation)
{
//Call initialize before proceeding to call the intercepted method
//Worth noting that this is the only place we actually call Initialize()
((ActualClass)invocation.InvocationTarget).Initialize();
invocation.Proceed();
}
}
class Program
{
static void Main(string[] args)
{
ActualClass instance1 = ActualClass.getActualClassInstance();
ActualClass instance2 = ActualClass.getActualClassInstance();
int x1 = instance1.replaceValue(41);
int x2 = instance2.replaceValue(42);
int y1 = instance1.replaceValue(82);
Debug.Assert(y1 == 41);
int y2 = instance2.replaceValue(84);
Debug.Assert(y2 == 42);
var read = Console.ReadKey();
}
}
}
Methods specific for customers:
I try to refactore a code, where are a lot of logic for specifi customer:
public void SendDocumentsToCustomer(List<Case> cases)
{
foreach(var case in cases)
{
if(case.CustomerId==123)
{
if(case.Type==1 || case.Type==2)
{
SendDocumentsToCustomer123(case)
}
else if(case.CustomerId==456)
{
if(case.Type==1 || case.Type==3)
{
SendDocumentsToCustomer456(case);
}
}
else if(case.CustomerId==768)
{
if(case.Type==2)
{
SendDocumentsToCustomer456(case);
}
else
{
SendDocumentsToCustomer(case);
}
}
}
The list of specific customer will grow, and the conditions will be modified as well. I will have a generic solution, but maybe code like this with method DoItForClient123 is not a bad solution and I should leave it like that and goint this way introduce methods like CanDocumentsBeSendToClient123 and so on?
I will be very gratefull for some input
To separate logic for each specific customer I would use such code:
abstract class DocumentSender //Base class for all document sending components
{
public abstract bool CanSend(Case #case); // Check if sender can send the document
public abstract void SendDocument(Case #case); // Send the document
}
class DefaultDocumentSender : DocumentSender
{
public override bool CanSend(Case #case)
{
return true; //Can process all requests
}
public override void SendDocument(Case #case)
{
// Do something
}
}
class Customer123DocumentSender : DocumentSender
{
public override bool CanSend(Case #case)
{
return #case.CustomerId == 123; //Specific case
}
public override void SendDocument(Case #case)
{
if(#case.Type==1 || #case.Type==2)
{
// Do something different
}
}
}
//Separate class for getting the correct sender
class CaseSenderFactory
{
readonly List<DocumentSender> _senders = new List<DocumentSender>();
public DocumentSenderFactory()
{
//Initialize the list of senders from the most specific.
_senders.Add(new Customer123DocumentSender());
// Add more specific cases here
_senders.Add(new DefaultDocumentSender()); //Last item should be the default sender
}
public DocumentSender GetDocumentSender(Case #case)
{
//At least one sender needs to satisfy the condition
return _senders.First(x => x.CanSend(#case));
}
}
You then can use the senders like this:
var factory = new DocumentSenderFactory();
foreach(var #case in cases)
{
var sender = factory.GetDocumentSender(#case);
sender.SendDocument(#case);
}
I think it would be a good ideea to make something like this:
The ideea is if the code is really specific to some of the Customers then you could make a class for them. If the code for specific customers somehow related but combined in a diferent way then you should take a loot at DecoratorPattern(mabye it helps)
class Customer
{
public abstract SendDocumentsTo(Customer c);
}
class SpecificCustomerA
{
public overwrite SendDocumentsTo(Customer c)
{
if (c is SpecificCustomerB)
{
//Logic here
}
}
}
class SpecificCustomerB { ... }
Consider the following control (snipped for brevity):
public partial class ConfigurationManagerControl : UserControl
{
public Func<string, bool> CanEdit { get; set;}
public Func<string, bool> CanDelete { get; set; }
public Dictionary<string, string> Settings
{
get { return InnerSettings; }
set
{
InnerSettings = value;
BindData();
}
}
private Dictionary<string, string> InnerSettings;
private void OnListIndexChanged(object sender, EventArgs e)
{
this.EditButton.Enabled = false;
this.DeleteButton.Enabled = false;
var indices = this.List.SelectedIndices;
if (indices.Count != 1)
{
return;
}
var index = indices[0];
var item = this.List.Items[index];
if (this.CanEdit != null)
{
this.EditButton.Enabled = this.CanEdit(item.Text);
}
if (this.CanDelete != null)
{
this.DeleteButton.Enabled = this.CanDelete(item.Text);
}
}
}
There's more to this control, but suffice it to say that it allows a user to add, edit, and delete the entries in a Dictionary<string, string>. In order to determine whether or not it should allow the user to edit or delete the entries, it uses the delegate method properties, CanDelete and CanEdit, which are provided by the form or control that hosts it:
public class SetupWizard : Form
{
public SetupWizard()
{
InitializeComponent();
this.SettingManager.CanEdit = CanEditSetting;
this.SettingManager.CanDelete = CanDeleteSetting;
}
private static bool CanEditSetting(string item)
{
var lockedSettings = new[] { "LicenseHash", "ProductHash" };
return !lockedSettings.Contains(item.ToLower());
}
private static bool CanDeleteSetting(string item)
{
var lockedSettings = new[] {
"LicenseHash",
"ProductHash",
"UserName",
"CompanyName"
};
return !lockedSettings.Contains(item.ToLower());
}
}
I find that this design is both satisfactory and worrisome at the same time. On the one hand, it seems to solve the problem using the simplest solution that works (it certainly separates the concerns nicely). On the other hand, I have this nagging concern that I am using delegates improperly and should be using an event, instead (even though I do not need multiple listeners, and only need the caller to tell me if the item is editable).
And then, on the other other hand, there's the chance that there's a completely different design that I haven't even considered that might solve the problem in a vastly superior way.
So. Is this design technically correct, maintainable, and flexible? Or should I be doing something better?
I suggest the use of an interface with these two methods. That's a lot cleaner:
interface ICantThinkOfAGoodName
{
bool CanEdit(string item);
bool CanDelete(string item);
}
You could create something similar to the RelayCommand used in many MVVM frameworks:
public class RelayObject : ICantThinkOfAGoodName
{
public RelayObject() : this(null, null) {}
public RelayObject(Func<string, bool> canEdit, Func<string, bool> canDelete)
{
if(canEdit == null) canEdit = s => true;
if(canDelete == null) canDelete = s => true;
_canEdit = canEdit;
_canDelete = canDelete;
}
public bool CanEdit(string item)
{
return _canEdit(item);
}
public bool CanDelete(string item)
{
return _canDelete(item);
}
}
Use it like this:
public SetupWizard()
{
InitializeComponent();
this.SettingManager.PropertyName = new RelayObject(CanEditSetting,
CanDeleteSetting);
// or (all can be deleted)
this.SettingManager.PropertyName = new RelayObject(CanEditSetting, null);
// or (all can be edited)
this.SettingManager.PropertyName = new RelayObject(null, CanDeleteSetting);
// or (all can be edited and deleted)
this.SettingManager.PropertyName = new RelayObject();
}
BTW: I am using Property injection here, because it is a control. Normally, I would pass the ICantThinkOfAGoodName dependency in the constructor of the ConfigurationManagerControl.
It may be this is what #Daniel Hilgarth is suggesting when he says "use an interface" (n.b. - his answer now reflects a more general/flexible approach to implementing the interface). Instead of assigning delegates to your method directly, why not give the control a property, such as DataState or whatever you want to call it, using an interface that encapsulates the information you need, and leave it up to the owner to decide how to implement that.
interface IDataState
{
bool CanEdit(string item);
bool CanDelete(string item);
}
public partial class ConfigurationManagerControl : UserControl
{
public IDataState DataState {get;set;}
// your code checks DataState.CanEdit & DataState.CanDelete
}
public class SetupWizard : Form, IDataState
{
public SetupWizard()
{
InitializeComponent();
SettingManager.DataState =this;
}
public bool CanEdit(string item)
{
... implement directly or return from your private function
}
public bool CanDelete(string item)
{
}
}
But this gives you the flexibility to implement that interface any way you choose, with another object, etc. and it makes it easy to also just pass the owner itself (implementing the interface).