I'm working on the legacy asp.net code (however it was converted to newest .net version), I encountered file which contains 15 500 long if-elseif block (with 700 conditions). Each condition is of the same structure:
if(a == "aaa")
{
.....
}
else if(a == "bbb")
{
....
}
.....
I think it needs to be refactored. I want to split the code from each block into separe classes, name them as "aaa", "bbb", ... and use Dictionary or Hashtable to store references to them. It would probably have an Interface with method execute() with the certain return type. The problem is that I think instantiation of each class and storing the objects to hash table would take some time and I believe that performancewise it would be worse thing (for each request constructing hashtable). It would have to store total of 700 objects and then it would retrieve only one object. My questions are:
Is there any better way of solving such a problem? For example, maybe I shall store classes instead of objects, and then use reflection to instantiate class and call its method?
How painful it would be performance wise to apply such design (dividing if/else if blocks into classes -> add objects (which implement certain interface) to dictionary --> take one object from dictionary
Let's say I put all the classes to folder F, how could I retrieve all the classes and add them to dictionary
Any suggestions, other ways to solve the problem?
Well, if you don't need instance variables, I would recommend a static class with each of these as a separate function. Then you can define a compatible delegate method, and store references to the functions themselves rather than the classes. Since they'd be executed in a static context, there would be no need for class instantiation.
It would require a bit of memory to load up the hash map, but after that the footprint would be negligible.
Related
If I have a method outside it's callers scope that does a few things, and I have to call this method multiple times in multiple places. Is there any way to make the entire scope of the caller available to the method without passing parameters and also without using global variables? Like if I need it to have an access to a List, an entity framework context
Instead of
myMethod(string _string, List<string> _stringList, EntityContext _db)
{
//log _string to a database table
//add _string to _stringList
//etc.
}
Is there a way I can just pass the _string and make the method inherit the scope as if I'm just writing the same three lines of code everywhere I call this method? It seems a lot cleaner to call myMethod("foo") than myMethod("foo", stringList, MyEntities).
I could create a class, instantiate it, and call the class, but I'm just plain curious if scope inheritance or scope passing is a thing.
Absolutely don't do that. If you have a context you need to pass, use a class to represent the context needed, but don't try to handwave it away and hide it. It makes for unmaintainable code full of interdependencies.
In fact, the "bother" or "overhead" of passing the context object around is a good thing: it points out that having dependencies between the elements of your software project is not free. If you think that writing out the extra parameter is "too much work", then you're missing the forest for the trees: the dependency thus introduced has a much higher mental overhead than the mere mechanics of typing an extra parameter. After you pass that context a few times, typing it will be second nature and have 0 real overhead. The typing is cheap and doesn't require thinking, but keeping in mind the dependency and how it figures in the design of the overall system is anything but.
So: if you are trying to argue that introducing the dependency is worth it, then you have to back it up with actions and actually pass the context object around. The real cost is in the dependency, not the typing. Otherwise, it's a case of "talk is cheap" :)
One way of decreasing the apparent "cost" of passing such context objects is to upset the balance and make the context object actually do something, besides just carrying data. You would then use the context object to manipulate the objects for you, instead of calling the methods on the objects. This sort of "inversion" is quite handy, and often results in better design. After all, the presence of the context indicates that there's an overarching common state, and that perhaps too much functionality is delegated to the "end object", making it intertwined with the common state, whereas it may make more sense in the context object, making the end object less dependent on the presence of any particular external state.
You'd want the context to have methods that require "seeing the big picture", i.e. being aware of the presence of multiple objects, whereas the "leaf objects" (the ones with myMethod) should have methods that don't require the context, or that are general enough not to force any particular context class.
In your case, myMethod perhaps instead of working directly on an EntityContext could generate a functor or a similar action-wrapping object that performs the action, and this could then be applied by the caller (e.g. the context) to execute the database action. This way later it'll be easier to centrally manage the queue of database operations, etc.
When I refactor large projects, this sort of a "context inversion" comes in handy often, and the need for such patterns is very common. Usually, as large projects grow, the "leaf classes" start up lean, and end up acquiring functionality that belongs at a higher level. This is why using good tooling to explore the history of the repository is an imperative, and it's equally important that the entire repository history is available, i.e. that it was properly imported to git. I personally use DeepGit to trace the history of the code I work on, and find such tool indispensable. DeepGit is free as in beer for any use, and if you're not using a tool with similar functionality, you're seriously missing out, I think.
The need to pass contexts around is usually the indicator that a higher level has to be designed and introduced, and the "leafs" then need to be slimmed down, their context-using functionality moved out into the higher level. A few years down the road yet another higher level ends up being needed, although there are projects so far gone that when you just refactor them to make sense of the code base, two or three additional layers make themselves apparent!
I know of 2 ways that can be done. Consider you have the following method:
static void myMethod(string _stringA, string _stringB, string _stringC)
{
Console.WriteLine($"{_stringA},{_stringB},{_stringC}");
}
Create an overload method in the class. For example you could create an overloaded method like:
static void myMethod(string _stringA)
{
myMethod(_stringA, "stringB", "stringC");
}
The second way (which I would not advice it) is doing it the functional way like Javascript does (by using delegates):
public delegate void MethodDelegate(string _string);
static MethodDelegate mMethod1;
static MethodDelegate mMethod2;
static void Main(string[] args)
{
mMethod1 = delegate (string s) { myMethod(s, "method1-str-a", "method1-str-b"); };
mMethod1("str1");
mMethod2 = delegate (string s) { myMethod(s, "method2-str-a", "method2-str-b"); };
mMethod2("str2");
}
When I first began as a junior C# dev, I was always told during code reviews that if I was accessing an object's property more than once in a given scope then I should create a local variable within the routine as it was cheaper than having to retrieve it from the object. I never really questioned it as it came from more people I perceived to be quite knowledgeable at the time.
Below is a rudimentary example
Example 1: storing an objects identifer in a local variable
public void DoWork(MyDataType object)
{
long id = object.Id;
if (ObjectLookup.TryAdd(id, object))
{
DoSomeOtherWork(id);
}
}
Example 2: retrieving the identifier from the Id property of the object property anytime it is needed
public void DoWork(MyDataType object)
{
if (ObjectLookup.TryAdd(object.Id, object))
{
DoSomeOtherWork(object.Id);
}
}
Does it actually matter or was it more a preference of coding style where I was working? Or perhaps a situational design time choice for the developer to make?
As explained in this answer, if the property is a basic getter/setter than the CLR "will inline the property access and generate code that’s as efficient as accessing a field directly". However, if your property, for example, does some calculations every time the property is accessed, then storing the value of the property in a local variable will avoid the overhead of additional calculations being done.
All the memory allocation stuff aside, there is the principle of DRY(don't repeat yourself). When you can deal with one variable with a short name rather than repeating the object nesting to access the external property, why not do that?
Apart from that, by creating that local variable you are respecting the single responsibility principle by isolating the methods from the external entity they don't need to know about.
And lastly if the so-called resuing leads to unwanted instantiation of reference types or any repetitive calculation, then it is a must to create the local var and reuse it throughout the class/method.
Any way you look at it, this practice helps with readability and more maintainable code, and possibly safer too.
I don't know if it is faster or not (though I would say that the difference is negligible and thus unimportant), but I'll cook up some benchmark for you.
What IS important though will be made evident to you with an example;
public Class MyDataType
{
publig int id {
get {
// Some actual code
return this.GetHashCode() * 2;
}
}
}
Does this make more sense? The first time I will access the id Getter, some code will be executed. The second time, the same code will be executed costing twice as much with no need.
It is very probable, that the reviewers had some such case in mind and instead of going into every single one property and check what you are doing and if it is safe to access, they created a new rule.
Another reason to store, would be useability.
Imagine the following example
object.subObject.someOtherSubObject.id
In this case I ask in reviews to store to a variable even if they use it just once. That is because if this is used in a complicated if statement, it will reduce the readability and maintainability of the code in the future.
A local variable is essentially guaranteed to be fast, whereas there is an unknown amount of overhead involved in accessing the property.
It's almost always a good idea to avoid repeating code whenever possible. Storing the value once means that there is only one thing to change if it needs changing, rather than two or more.
Using a variable allows you to provide a name, which gives you an opportunity to describe your intent.
I would also point out that if you're referring to other members of an object a lot in one place, that can often be a strong indication that the code you're writing actually belongs in that other type instead.
You should consider that getting a value from a method that is calculated from an I/O-bound or CPU-bound process can be irrational. Therefore, it's better to define a var and store the result to avoid multiple same processing.
In the case that you are using a value like object.Id, utilizing a variable decorated with const keyword guarantees that the value will not change in the scope.
Finally, it's better to use a local var in the classes and methods.
I have a situation where I have to pass a List<> across 2-3 independent classes up and down the class. Right now I'm mostly passing the list using parameter so all 3 classes gets the list. Should I use a static list instead of passing List all over the classes to simplify the code like Class23.ListObjects.Add() and then release the static values once the operation is done so the next operation starts with an empty List. Right now it feels like the parameters are getting a lot and I'm getting confused if the list has the right values, forgetting to pass the list to the next class, etc. What do you think?
I would suggest you create a new class that represents the combined operation performed by the various classes (a "context" class, if you will). Values needed to perform the operation can be held as instance variables in that context, along with instances of the classes used in performing the work.
That way, you avoid passing stuff around (as code evolves, this can get somewhat ugly) while avoiding a "global" variable. Data is in exactly the scope it needs to be, and is disposed when the overall operation is complete.
In Coding practices, it is bad to have static or Global variables and passing through parameters is considered good.
If you use a static parameter, you run the risk of getting corrupted data if those functions are used in multiple places in your code, especially if threading is involved.
For instance, suppose Class A needs to use your functions that act on your static list. Before those functions are completed, Class B tries to use them as well, causing the list to get data from both calls, since the same static list is used in both cases.
i am building a sort of program that generates a random list of word according to a database.
I Made a class that deals with the word selecting and handling (a random select function, a connect to the database function etc..)
I have 3 variables that indicate the last 3 words chosen.
how do I use a funcion on the form1 (button 1 press), to manipulate the same 3 variables, without creating them from scratch everytime (what happens now...)
To make myself clearer:
accualy what I need is to know how to keep track of a variable between multiple classes.
I might be using the whole classes thing wrong... I am now triyng to get the grasp of it.
Thank you very much,
Barak.
Your two options as I see it are:
1) an instance of a class that holds those variables that can be passed around
You may want to use the singleton pattern for this class if you want to make sure there is only ever one of them.
2) A static class with static members holding this information.
It may be that your entire random word class could be static. In this case you'd just call the methods and properties on that class to generate and access your words.
Also I would suggest that you may want to consider a collection to hold your words rather than three separate variables. It will of course depend on your implementation so I will mention it just inc ase you haven't thought of it and I'm not saying you definitely should. :)
I would avoid static or Singletons just for this purpose - they're not good habits to pick up for simple object oriented scenarios.
Encapsulate the state variables in a class, which you instantiate first, then pass by reference into the form and/or data fetch logic.
Key to this is understanding the concept of reference - your form and fetch logic will see the same instance of your state class, effectively sharing it.
If you implement the "variables" as properties on the state class, you can use events to notify other parts of your code when the word states change.
Consider also clearly defining the possible interactions (interfaces) on the state class. One aspect seems to be to add a word, another to pull out statistics based on the added words. The state class can accommodate all this, and provide a nice place for future extensions.
Try to think in terms of public interface methods/properties, while keeping "variables" (i.e. fields like counters or collections) private.
I also agree that your post should be improved with snippets of actual code - help us helping you.
And I hope your code is not being used to generate spam mails/posts... :-)
I need to transfer .NET objects (with hierarchy) over network (multiplayer game). To save bandwidth, I'd like to transfer only fields (and/or properties) that changes, so fields that won't change won't transfer.
I also need some mechanism to match proper objects on the other client side (global object identifier...something like object ID?)
I need some suggestions how to do it.
Would you use reflection? (performance is critical)
I also need mechanism to transfer IList deltas (added objects, removed objects).
How is MMO networking done, do they transfer whole objects?
(maybe my idea of per field transfer is stupid)
EDIT:
To make it clear: I've already got mechanism to track changes (lets say every field has property, setter adds field to some sort of list or dictionary, which contains changes - structure is not final now).
I don't know how to serialize this list and then deserialize it on other client. And mostly how to do it effectively and how to update proper objects.
There's about one hundred of objects, so I'm trying avoid situation when I would write special function for each object. Decorating fields or properties with attributes would be ok (for example to specify serializer, field id or something similar).
More about objects: Each object has 5 fields in average. Some object are inherited from other.
Thank you for all answeres.
Another approach; don't try to serialize complex data changes: instead, send just the actual commands to apply (in a terse form), for example:
move 12432 134, 146
remove 25727
(which would move 1 object and remove another).
You would then apply the commands at the receiver, allowing for a full resync if they get out of sync.
I don't propose you would actually use text for this - that is just to make the example clearer.
One nice thing about this: it also provides "replay" functionality for free.
The cheapest way to track dirty fields is to have it as a key feature of your object model, I.e. with a "fooDirty" field for every data field "foo", that you set to true in the "set" (if the value differs). This could also be twinned with conditional serialization, perhaps the "ShouldSerializeFoo()" pattern observed by a few serializers. I'm not aware of any libraries that match exactly what you describe (unless we include DataTable, but ... think of the kittens!)
Perhaps another issue is the need to track all the objects for merge during deserialization; that by itself doesn't come for free.
All things considered, though, I think you could do something alon the above lines (fooDirty/ShouldSerializeFoo) and use protobuf-net as the serializer, because (importantly) that supports both conditional serialization and merge. I would also suggest an interface like:
ISomeName {
int Key {get;}
bool IsDirty {get;}
}
The IsDrty would allow you to quickly check all your objects for those with changes, then add the key to a stream, then the (conditional) serialization. The caller would read the key, obtain the object needed (or allocate a new one with that key), and then use the merge-enabled deserialize (passing in the existing/new object).
Not a full walk-through, but if it was me, that is the approach I would be looking at. Note: the addition/removal/ordering of objects in child-collections is a tricky area, that might need thought.
I'll just say up front that Marc Gravell's suggestion is really the correct approach. He glosses over some minor details, like conflict resolution (you might want to read up on Leslie Lamport's work. He's basically spent his whole career describing different approaches to dealing with conflict resolution in distributed systems), but the idea is sound.
If you do want to transmit state snapshots, instead of procedural descriptions of state changes, then I suggest you look into building snapshot diffs as prefix trees. The basic idea is that you construct a hierarchy of objects and fields. When you change a group of fields, any common prefix they have is only included once. This might look like:
world -> player 1 -> lives: 1
... -> points: 1337
... -> location -> X: 100
... -> Y: 32
... -> player 2 -> lives: 3
(everything in a "..." is only transmitted once).
It is not logical to transfer only changed fields because you would be wasting your time on detecting which fields changed and which didn't and how to reconstruct on the receiver's side which will add a lot of latency to your game and make it unplayable online.
My proposed solution is for you to decompose your objects to the minimum and sending these small objects which is fast. Also, you can use compression to reduce bandwidth usage.
For the Object ID, you can use a static ID which increases when you construct a new Object.
Hope this answer helps.
You will need to do this by hand. Automatically keeping track of property and instance changes in a hierarchy of objects is going to be very slow compared to anything crafted by hand.
If you decide to try it out anyway, I would try to map your objects to a DataSet and use its built in modification tracking mechanisms.
I still think you should do this by hand, though.