C#: simple vs complex objects and memory usage - c#

When dealing with large collections, which of the following approaches is better?
Class SimpleObject with only fields/properties and class SimpleObjectController that contains all the method implementations required by SimpleObject. At runtime, I build a collection of SimpleObjects, instantiate one SimpleObjectController and call it's methods, passing the SimpleObject I want to work with.
or
Class "ComplexObject" that aggregates the SimpleObject and SimpleObjectController in the traditional OO approach. At runtime I have a collection of ComplexObjects, iterate over them, calling their methods as needed.
It has been suggested to me that the first approach is preferable in terms of memory usage as all the heavyweight code is only in one object instead of each one in the collection. My understanding was that if we had 1000 of these objects in a collection, that doesn't mean there is 1000 of the same method implementations sitting in memory. There would be 1000 instances of the data, but they would share the one code instance (x86 code segment & data segment?). It also seems to fly in the face of general OO principles and encapsulation.

You should take the second approach. Code has no per-instance cost: there is one copy of the code for each class, not each instance. So there is no memory benefit to the first approach. And you're right, the OO style is to put the functions in with the data, in order to encapsulate them; if you took the first approach, somebody could easily mis-manipulate a SimpleObject by working with it directly instead of through the controller methods.

I don't imagine there would be any difference, besides having two class definitions instead of one.
You're correct in thinking that there isn't 1000 instances of the method implementations. Once compiled, all the methods become "global" methods that have a hidden ComplexObject argument that is mapped to the this keyword in C#.

Related

explicitly mark parameter as mutating in c#

I have a large amount of code that is dependent on a list of objects. the list is modified a lot while being passed around as a parameter to various methods.
Even though I understand the workings of this code, I feel uneasy letting such an easy opportunity to make a mistake exist. Is there a way to handle this situation in c# outside of a goofy comment or refactoring?
If you are passing a List<Something> around in your code, then it is "mutable" by default, and there is no way to signal this explicitly.
If this is a language background issue (Haskell?), then in C# you should looks things from a different perspective: if you wanted to pass around an immutable collection, you would need to use some different type (maybe an IEnumerable<Something>, even if it's not the same as a list); if you're passing around a List, instead, it can be modified by every method that receives it.
Maybe you can give that list a special type:
class MyCustomMutableList : List<int>
You could even not give it any base class to make sure that any usage site must use this special type in order to be able to access list data.
I would normally consider this a misuse of inheritance. If this is an implementation detail and does not leak out to consumers of your API it's probably good enough. Otherwise, create an IList<int> derived class through composition. R# has a feature to delegate all virtual methods to an instance field. That generates all that code.
You also could create a wrapper class that just exposes the required methods to perform the required mutations:
class DataCollector {
public void Add(int item) { ... }
}
Since all this object allows to do is mutation it is pretty clear that mutation is going on.

Optimize empty method calls in C#

I have an abstract class that is supposed to become the base of a huge hierarchy of classes. Among other things, it has a certain abstract method. During the execution, it will be called on all objects of this class constantly by a system that knows only about this abstract class and not it's children:
foreach( AbstractClass object in allTheObjects )
object.DoStuff();
However, a lot of it's children in fact don't override this method (which is empty in the base class); ones that use it and ones that don't a distributed among the class hierarchy. Will the C# take care of this empty method, or will I have to optimize it in some way?
P.S.: I know that premature optimization is evil, but it just got me really curious.
I wouldn't worry about that. In C#, method calls are really cheap. And even if you would optizmizie this, I doubt that you will see any differnce. See this post for reference.
I'd worry more about if you could avoid looping through everything, or what data strucutre allTheObjects is. I'd say there's much more potential for optimization there.
Also you might think about if you really need a big inheritance structure, or if you can achieve your goals with composition or interfaces.
You will also find more information here (interface methods vs. delegates vs. normal method calls)
However, a lot of it's children in fact will have this method empty
Maybe you need to declare this method as virtual instead of abstract? Thus you can provide default empty implementation.

Is it OK to have a class with just properties for refactoring purposes?

I have a method that takes 30 parameters. I took the parameters and put them into one class, so that I could just pass one parameter (the class) into the method. Is it perfectly fine in the case of refactoring to pass in an object that encapsulates all the parameters even if that is all it contains.
That is a great idea. It is typically how data contracts are done in WCF for example.
One advantage of this model is that if you add a new parameter, the consumer of the class doesn't need to change just to add the parameter.
As David Heffernan mentions, it can help self document the code:
FrobRequest frobRequest = new FrobRequest
{
FrobTarget = "Joe",
Url = new Uri("http://example.com"),
Count = 42,
};
FrobResult frobResult = Frob(frobRequest);
While other answers here are correctly point out that passing an instance of a class is better than passing 30 parameters, be aware that a large number of parameters may be a symptom of an underlying issue.
E.g., many times static methods grow in their number of parameters, because they should have been instance methods all along, and you are passing a lot of info that could more easily be maintained in an instance of that class.
Alternatively, look for ways to group the parameters into objects of a higher abstraction level. Dumping a bunch of unrelated parameters into a single class is a last resort IMO.
See How many parameters are too many? for some more ideas on this.
It's a good start. But now that you've got that new class, consider turning your code inside-out. Move the method which takes that class as a parameter into your new class (of course, passing an instance of the original class as the parameter). Now you've got a big method, alone in a class, and it will be easier to tease it apart into smaller, more manageable, testable methods. Some of those methods might move back to the original class, but a fair chunk will probably stay in your new class. You've moved beyond Introduce Parameter Object on to Replace Method with Method Object.
Having a method with thirty parameters is a pretty strong sign that the method is too long and too complicated. Too hard to debug, too hard to test. So you should do something about it, and Introduce Parameter Object is a fine place to start.
Whilst refactoring to a Parameter Object isn't in itself a bad idea it shouldn't be used to hide the problem that a class that needs 30 pieces of data provided from elsewhere could still be something of a code smell. The Introduce Parameter Object refactoring should probably be regarded as a step along the way in a broader refactoring process rather than the end of that procedure.
One of the concerns that it doesn't really address is that of Feature Envy. Does the fact that the class being passed the Parameter Object is so interested in the data of another class not indicate that maybe the methods that operate on that data should be moved to where the data resides? It's really better to identify clusters of methods and data that belong together and group them into classes, thereby increasing encapsulation and making your code more flexible.
After several iterations of splitting off behaviour and the data it operates on into separate units you should find that you no longer have any classes with enormous numbers of dependencies which is always a better end result because it'll make your code more supple.
That is an excellent idea and a very common solution to the problem. Methods with more than 2 or 3 parameters get exponentially harder and harder to understand.
Encapsulating all this in a single class makes for much clearer code. Because your properties have names you can write self-documenting code like this:
params.height = 42;
params.width = 666;
obj.doSomething(params);
Naturally when you have a lot of parameters the alternative based on positional identication is simply horrid.
Yet another benefit is that adding extra parameters to the interface contract can be done without forcing changes at all call sites. However, this is not always as trivial as it seems. If different call sites require different values for the new parameter, then it is harder to hunt them down than with the parameter based approach. In the parameter based approach, adding a new parameter forces a change at each call site to supply the new parameter and you can let the compiler do the work of finding them all.
Martin Fowler calls this Introduce Parameter Object in his book Refactoring. With that citation, few would call it a bad idea.
30 parameters is a mess. I think it's way prettier to have a class with the properties. You could even create multiple "parameter classes" for groups of parameters that fit in the same category.
You could also consider using a structure instead of a class.
But what you're trying to do is very common and a great idea!
It can be reasonable to use a Plain Old Data class whether you're refactoring or not. I'm curious as to why you thought it might not be.
Maybe C# 4.0's optional and named parameters be a good alternative to this?
Anyway, the method you are describing can also be good for abstracting the programs behavior. For example you could have one standard SaveImage(ImageSaveParameters saveParams)-function in an Interface where ImageSaveParameters also is an interface and can have additional parameters depending on the image-format. For example JpegSaveParameters has a Quality-property while PngSaveParameters has a BitDepth-property.
This is how the save save-dialog in Paint.NET does it so it is a very real life example.
As stated before: it is the right step to do, but consider the followings too:
your method might be too complex (you should consider dividing it into more methods, or even turn it into a separate class)
if you create the class for the parameters, make it immutable
if many of the parameters could be null or could have some default value, you might want to use the builder pattern for your class.
So many great answers here. I would like to add my two cents.
Parameter object is a good start. But there is more that could be done. Consider the following (ruby examples):
/1/ Instead of simply grouping all the parameters, see if there can be meaningful grouping of parameters. You might need more than one parameter object.
def display_line(startPoint, endPoint, option1, option2)
might become
def display_line(line, display_options)
/2/ Parameter object may have lesser number of properties than the original number of parameters.
def double_click?(cursor_location1, control1, cursor_location2, control2)
might become
def double_click?(first_click_info, second_click_info)
# MouseClickInfo being the parameter object type
# having cursor_location and control_at_click as properties
Such uses will help you discover possibilities of adding meaningful behavior to these parameter objects. You will find that they shake off their initial Data Class smell sooner to your comfort. :--)

Why are Constructors Evil?

I recall reading an article about constructors being evil (but can't place it). The author mentioned that constructors are a special case of methods; but have restrictions (such as that they cannot have a return value).
Are constructors evil? Is it better to have no constructors and instead rely on a method like Initialize, along with default values for member variables?
(Your answer can be specific to C# or Java, if you must pin down a language.)
That sounds like Allen Holub. One might argue that constructors are evil solely to drive web traffic :) They are no more evil than any other language construct. They have good and bad effects. Of course you can't eliminate them -- no way to construct objects without them!
What you can do, though, and this is the case that Allen was making, is you can limit your actual invocation of them, and instead favor, when sensible, factory methods like your Initialize. The reason for this is simple: it reduces coupling between classes, and makes it easier to substitute one class for another during testing or when an application evolves.
Imagine if your application does something like
DatabaseConnection dc = new OracleDatabaseConnection(connectionString);
dc.query("...");
and imagine that this happens in a hundred places in your application. Now, how do you unit test any class that does this? And what happens when you switch to Mysql to save money?
But if you did this:
DatabaseConnection dc = DatabaseConnectionFactory.get(connectionString);
dc.query("...");
Then to update your app, you just have to change what DatabaseConnectionFactory.get() returns, and that could be controlled by a configuration file. Avoiding the explicit use of constructors makes your code more flexible.
Edit: I can't find a "constructors" article, but here's his extends is evil one, and here's his getters and setters are evil one.
They aren't. In fact, there is a specific pattern known as Inversion of Control that makes ingenious use of Constructors to nicely decouple code and make maintenance easier. In addition, certain problems are only solvable by using non default constructors.
Evil? No.
Calling a constructor does require that you call "new", which does tie you to a particular implementation. Factories and dependency injection allow you to be more dynamic about runtime types, but they require programming to interfaces.
I think the latter are more flexible, but constructors evil? That's going too far, just like having an iterface for everything goes too far.
Constructors aren't evil, but (at least in Java) often it's better to use static Factory methods instead (which of course use constructors internally).
Here are a few quotes From Effective Java, Item 1: Consider static factory methods instead of constructors:
One advantage of static factory
methods is that, unlike constructors,
they have names. If the parameters to
a constructor do not, in and of
themselves, describe the object being
returned, a static factory with a
well-chosen name is easier to use and
the resulting client code easier to
read.
...
A second advantage of static factory
methods is that, unlike constructors,
they are not required to create a new
object each time they’re invoked. This
allows immutable classes (Item 15) to
use preconstructed instances, or to
cache instances as they’re
constructed, and dispense them
repeatedly to avoid creating
unnecessary duplicate objects.
...
A third advantage of static factory
methods is that, unlike constructors,
they can return an object of any
subtype of their return type.
...
A fourth advantage of static factory
methods is that they reduce the
verbosity of creating parameterized
type instances. Unfortunately, you
must specify the type parameters when
you invoke the constructor of a
parameterized class even if they’re
obvious from context. This typically
requires you to provide the type
parameters twice in quick succession:
Map<String, List<String>> m =
new HashMap<String, List<String>>();
...
The main disadvantage of providing
only static factory methods is that
classes without public or protected
constructors cannot be subclassed.
...
A second disadvantage of static
factory methods is that they are not
readily distinguishable from other
static methods.
Constructors allow initialization lists and other useful things. There's no way to dynamically initialize an object in an array (that doesn't use pointers to objects) without a copy constructor.
No they aren't evil.
They are special cases.
Constructors are not evil. They exist so that code can be run when an instance of a class is initialized. Just as with any other programming concept, if they aren't used right they can be a disaster to work with. But, if used correctly, they can be a great (and essential) tool.
http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)
I wouldn't say constructors are evil.
Constructors return a reference to the Object you are instantianting and should be used to set an object up to a default state. I can see benefits of using an Initialize method but there isn't much point. UNLESS you need to initialize some logic AFTER the object has been allocated stack space and initial values.
Constructors are not evil. Whatever article you read is wrong and you're better off having forgotten the link.
Constructors are not evil nor are they good. Constructors are a tool that can be very helpful if used properly and in the correct context. In fact at least in .NET languages such as C# if you do not explicitly declare a constructor in your code a constructor will be created for you by the compiler with no functionality.
Constructors are good when following normal OO programming paradigms. There are situations where you might need to place extra constraints on how objects are created, so in some cases a Factory pattern with private ctors might be a better fit. There is also a philosophy/best practice that says object instantiation should be the same as initialization, in which case constructors are the only real option outside factories that you have.
(factories still use constructors internally of course)
The question may not be about constructors in Java or C#, but constructors in javascript. In Javascript constructors can be a source of subtle errors. A lot of Javascript books recommend that beginners steer clear of constructors.
For a more detailed discussion of the evilness of constructors, and the new keyword, in javascript look : Is JavaScript's "new" keyword considered harmful?
I picked up this sort of vibe, to a degree, from Miško Hevery's talk "Don't look for things" which is available on YouTube. Part of the outlining discussion he gives, I interpret as a criticism of 'fat constructors', if not constructors in general.
The point of this argument, at least as I understood it, was that constructors that take in everything the object wants encourage you to enforce correctness using the constructor, instead of enforcing correctness with tests. Constructors do tend to bloat to do exactly that, so if this bothers you, you could consider it an evil streak in the concept of the constructor. In the talk he says he prefers to only require an object to 'have' another object when it's needed to do something, rather than requiring it on construction.
Here's one article that considers whether constructors are harmful, not "evil". It's mostly in the context of JavaScript/Es6 but the arguments may hold for any language which has constructors.
The argument is really about user-defined constructors, you still need to call the system provided default constructors, else you could not create any instances at all.
The simplest argument is that if you can do the same thing with static methods as with custom constructors, isn't it better to choose one of the approaches and always stick to that, except if there is a specific reason not to.
That makes your program simpler in total and thus less error-prone. Note that Smalltalk never had "constructors".
https://medium.com/#panuviljamaa/constructors-considered-harmful-c3af0d72c2b1

What is better? Static methods OR Instance methods

I found that there are two type of methods called static methods and instance methods and their differences.
But still I couldnt understand the advantages of one over another.
Sometimes i feel that static methods are not 100% object oriented.
Are there any performance differences between this two.
Can someone help?
In a perfect OO world there probably wouldn't be any need for static methods (I think Eiffel doesn't have them, either). But at the end of the day what matters is not OO-pureness of your code (C# has enough concepts that aren't strictly pure OO, like extension methods, for example) but rather what you're getting done.
You can use static methods for general helper methods (that don't need a general helper class or state on their own) or things like Color.FromARGB() which behave slightly contructor-like for value types.
In general, any method that doesn't touch an objects state (and therefore is more class-specific than object-specific) can be made static. Performance differences shouldn't really arise. Not very measurable, in any case. Jan Gray's great article Writing faster managed code: Know what things cost has some hard data on this, albeit to be taken with care.
The usefulness of a static method primarily comes when you need to call the method without ever instantiating the object. For example, maybe the static method is there to actually look up an existing instance and return it (an example being a singleton instance).
As others have stated, you can make any method static if it doesn't access state, and you'll get a tiny performance improvement.
If you actually want to be able to call the method on a specific instance though, and get the benefits of polymorphism (i.e. a derived class can override the behaviour of the method), then you should make the it an instance method.
If your classes implement interfaces, then the methods belonging to those interfaces must also be declared as instance methods.
Instance methods are tight to an instance. So you could see one advantage of static methods is not being tight to an instance. Static methods can (if visible) used by other objects to solve their problems. Sometimes this good and needed. Then you have to think about keeping your static methods in the same class or if you start building utility classes for broader use.
I wouldn't see the use of static methods of being "less OO". Static methods is one way to circumvent the shortcomings of OO (especially in single inheritance languages). You can call it a more functional approach (I know it isn't really).
Taking all this is just a bunch of questions that you should ask your code and that should determine if it is better an instance method, a static method of the same class or a static method of another class.
I wouldn't even think about performance issues. It will weaken your design and the difference isn't really that big. Performance is important if you have performance problems.
Instance methods require passing an implicit parameter (the this reference) which make them slightly slower than static methods. But that really should not be the reason to prefer them.
For a related discussion, look at:
Should C# methods that *can* be static be static?
If your method uses non-static data members, don't make it static (you "can't").
If your method does not use any non-static data members, you can make it static, but that mostly depends on your design rather than on whether it uses or not uses non-static members (there's not much difference in performance anyway as Mehrdad said).
If you have NO non-static data members in your class, sometimes it's a best practice to make all the methods static (like in the case of grouping helper functions under one class for the sake of good order).
I'm partially guessing based on the heritage of C# but I suspect it's the same as the other OO languages.
Static methods do not require an object to work on. A good example is something like:
Double pi = Math.PI.
Instance methods do require an object. An example is along the lines of:
Integer x = 9;
Integer y = x.sqrt();
Not all information belonging to a class should need an object instantiated for that class to get access to it. All those constants which can be used for creation of objects (Math.PI, Window.OVERLAPPED, etc) are prime examples of this.
No one is better than the other. It really depends on your requirement. Class methods are called when you want to apply a change to class as a whole. Whereas Instance methods are called when you are not applying change to the class but to a unique instance (object) of that class.
So I dont see a reason why one should be better than the other.

Categories