When do you feel that you need a new class (maybe when you are developing or after development for refactoring purpose)?
Maybe I can start from my existing variables and think how I can reorganize them into some classes! Please add more!
0
Primary reason to use a class is that there is a concept in domain you are trying to express in your code and you want to codify this concept in some way. Usually, classes are created when you, as a developer, see, through your years of experience, that there is a concept in what you are trying to achieve and you want to explicitly convert this concept into code.
But also, many of the concept show up after you have written the code, quite often as various code smells. There are two examples :
Multiple values being passed around together.
Be it Point or Customer, you can sometimes see that there are multiple (3+) variable all being passes around together. Code usually needs all, or most of those variables and even if it doesn’t directly need them, it’s dependencies might do. This is great opportunity to introduce a class to encapsulate all those variables. After that, you realize that many of the functions that work on those fields could actually be part of the class itself. And then, you might realize this is a concept within your domain, that you missed when doing analysis or design.
Big functions
It happened multiple times to me, that I found a function that was just too long. But when I tried to divide it into smaller functions, it resulted in all of the function’s state being passed around in parameters. This is great opportunity to introduce a class to represent the whole function itself. The function’s parameters might become a classe’s constructor. The function’s variables become fields. And then, you can easily separate the big function into smaller ones, because they all use shared state instead of relying on parameter passing. And then, you realize some of the if
s and switch
es might be represented as subclasses instead of code flow constructs, creating rich, maintainable and expressive representation instead of one huge hard-to follow and maintain function. This should make you think : if this piece of code was so complex, shouldn’t it be some kind of concept in domain I’m working in?
Classes as “structures with functions”
You are saying you have experience with procedural programming. Then you must know about structures and their use cases. Structures and classes overlap in many of those use cases. Some people even say that classes are just structures with functions bolted onto them and that they are no different than procedural programming. While I disagree, it might be good way for you to start thinking about classes. So whenever you would create a structure, you instead create a non-static class. The rest then follows.
Transparent dependencies and control flow
Another problem with static classes is that of dependency. If method of a class is static, then it becomes hard to tell what code actually uses this method. It becomes even worse problem if static state (in form of static fields) is involved. It becomes extremely hard to follow the flow of a code when you don’t know what other methods might be involved. If you use non-static classes, it becomes much cleaner, because you know what piece of memory method can modify, instead of working with global state. Actually, global state is the keyword here. It is generally known problems with global state range from pain in the ass to total nightmare. You should be striving to minimize amount of global state in your programs. Usage of non-static classes should be prioritized over static classes whenever possible.
0
In OOA&D I would like to know how you easily distinguish if a class is non-static?
Why? In OO, static classes should be very rare (if your language allows them at all). Your IDE will quickly tell you that there is no constructor for that class, and if not your IDE, the compiler surely will.
But for the one who is used to procedural programming how he can think of classes and the necessity for objects?
Practice. Objects aren’t a necessity. But getting into the train of thought to look at problems from a “what bundles of data/behavior make up this problem?” perspective rather than a “what steps do I need to take to solve this problem?” perspective takes time and practice.
Objects also have state and are mutable.
No.
In modern OO design, objects very often are not mutable. They more often have state, but even that is not a good rule of thumb for making objects. Many of the OO design patterns (strategy, most factories, some visitors, etc.) will use objects that contain no state.
I would like some rules of thumb or a short definition to easily distinguish classes in any project.
There are no universal rules of thumb. Are there rules of thumb for what functions to make in procedural programming? No, it will vary based on what problem you face, the language you’re using and your particular coding style. Even skilled programmers will often disagree about where the lines should be drawn to split up classes.
7
Using classes make your program shorter and more clear (Actually if the program is not too simple). Classes can encapsulate some of your existing variables and the related methods. Each class represents a concept which in turn makes finding and understanding of the solution easier.
To clarify these I give an example:
1- Suppose a program which takes the dimensions of a rectangle and calculate its area,
it could be:
static void Main()
{
int w,h;
read(w,h);
int a = calcArea(w,h); // it simply returns w x h
print(a);
}
2- A program which takes three rectangles in different coordinates and prints the intersect area of them, the old approach gives you
static void Main()
{
int x1,y1,w1,h1,x2,y2,w2,h2,x3,y3,w3,h3; // for rectangles
int x4,y4,w4,h4; // for the intersect
calcIntersect(x1,y1,w1,h1,x2,y2,w2,h2,x3,y3,w3,h3,x4,y4,w4,h4);
}
void calcIntersect(int x1,int y1,int w1,int h1,int x2,
int y2,int w2,int h2,int x3,int y3,int w3,int h3,
int& x4,int& y4,int& w4,int& h4)
{
// a fancy algorithms which works with this bunch of dimensions, its scary!!
}
As you have multiple objects the need for class is felt, then you would have:
class Rectangle
{
public int x,y,w,h;
}
// in your main
static void Main()
{
Rectangle r1,r2,r3, r4; //r4 for intersect
}
Now instead of thinking of dimensions think of rectangles as a new concept!…., I can calculate the intersect of two rectangles which is itself a rectangle and the same procedure gives me the intersect of this rectangle with the third one. You observe that this new concept makes finding the solution easier.
class Rectangle
{
public int x,y,w,h;
Rectangle Intersect(Rectangle r)
{
// now the situation is much better
}
}
static void Main()
{
Rectangle r1,r2,r3,r4;
Rectangle temp = r1.Intersect(r2);
r4 = r3.Intersect(temp);
}
9
Simple: static classes are exceedingly dumb. If you think you have identified a case for a static class, then stop- because you haven’t. You may have identified a namespace.
There are no static classes in OOP.