I am increasingly aware that my code in any single file can often span hundreds of lines quite easily and although I know the implementation might be sound, it still feels messy and unorganised.
I understand that there are situations where a lot of code is neccessary, but whats the best way to organise it all?
I've thought about separating variables from methods, privates from publics and internals but I don't want to because I can't help thinking that the components of ONE class belong in ONE file.
This whole thing is compounded when I'm working with the codebehind of a WPF window, which always seem to grow at an exponential rate into one huge mess very quickly.
Also: C# has a keyword called partial, which allows you to split a class over any number of files without affecting the functionality. However, I have noticed that Microsoft only seem to use partial to hide generated code from you (Winforms / WPF.) Which leads me to question whether splitting a class simply because it has many lines is a legitimate use of partial - is it?
Thanks
Separate your code into responsibilities. For each responsibility, define a single type. That is, follow the Single Responsibility Principal. Doing so will result in smaller units of code, each of which performs a very specific function. Not only does this result in smaller files, but also in better design and maintainability.
If your files are big because they contain a single class/struct that is big, then this is usually (but not always) a hint that your class is dealing with multiple concerns and can be refactored into a number of smaller, more specialised classes.
If I understand you, your main problem is that your forms end up being too big, which leads to the classes for those forms containing too much code, which is quite normal if your forms aren't very simple. The way to try minimize this is by using User Controls since if you move the controls to other classes, you also move the code behind to other classes.
It can sometimes make it a little more difficult to communicate between the controls, but that's usually more than made up for by the fact that the code in each class will be much easier to understand.
I tend to group properties, constructors, methods, and helper methods (private methods) together with regions. If I have a lot of methods, I create more regions based on what they do (especially good for overloads). And speaking of overloads, try minimizing your code with optional parameters.
As far as I understand partial means that the class exists in two separate files. Webforms and controls are partial because the other "part" of the file is the as[p|c]x file that goes with it.
I go on the theory that if you cant see an entire method on one screen (i.e. you have to scroll), you should break the method up into further methods - either in the same class or when the code will get used more than once into a helper class.
We use stylecop. It helps a bit because it enforces a structure on your code and an order for what should appear where. Hence you can then find your way around larger files a bit more intuitively.
To improve code readability: you can use the region block: https://msdn.microsoft.com/en-us/library/9a1ybwek.aspx . As for improving the structure and design of your code - consult some specialist books.
Related
I want to ask pro developers out there that how they manage a big windows form class. Is it a good idea to split it with partial keyword across different files? That's the thing that I was doing so far, but it creats unnecessry designer files that when you double click on them in VS, a blank winform will pop up:
So what I do, basically is group events and code logic for each related group of controls in one file.
My answer is "I don't". If you need a lot of code in one single class (in this case a form) it usually means your class is doing a lot of stuff and you need to make it less coupled. A good way to achieve this is to use a sort of MVC or MVP pattern form putting the logic in another place, and to use UserControls so you could have the different functionalities in different controls (with their controller or presenter, depending if you implement MVC or MVP). Divide and conquer.
I not consider me an expert, but once we had a similar problem with a main form that did not stop growing up.
The solution was just OOP, make unattached and reusable classes, those can be in the same namespace with internal visibility.
For Example there you have a ComparisionForm.Menu that looks that can be unattached from your main code in ComparisionForm.
From another point of view 'Readability'.- Partial classes are useful but take into account that even with that division of code in different files, the logic is not always divided, that makes the code hard to read, understand and finally hard to maintain.
Divide logically my classes for my was the solution. You know what say they "Divide and Conquer"
I think the best way to separate the code of a form, it's to use UserControl.
And in my case, when I have a big class, I use region instead of partial class.
Not a pro, but my two cents are: Don't have a large class. Extract most of the code to other classes.
You'll gain, also, that you'll be able to make most of the methods private, thus reducing Intellisense "noise".
A class is too large and becomes unwieldy to work with. In Objective-C I'd be tempted to use Categories to break the class up, but then: wouldn't categories just be dividing a house full of too much junk into rooms? The same question applies to partial classes in C#, I suppose.
Under what conditions can categories be used to solve a "class too large" code smell? When is it not correct and the class really needs to "be restructured or broken into smaller classes?"
A very good principle to refer to is the SOLID principle. In particular the "S" stands for "Single responsibility"
Single responsibility principle
the notion that an object should have only a single responsibility.
When classes get too big, it is likely they have too many responsibilities. Can you define two or more responsibilities within the boundaries of what the class is doing? If so, separate it into two, or more, classes. You can then aggregate them back using a façade or composite pattern.
In other words:
the code you have in the class should be split in different classes according to the Single Responsibility principle
the original God class becomes a composite or façade: it uses all the new classes, exposes the same methods to the rest of the system, but does not implement any functionality in itself, besides "converting" the old-style god-class calls in the new-style SOLID calls.
This means that regions do exactly nothing to solve your problem, from an object-oriented point of view. In fact, they are actually counterproductive as they contribute to hiding the problem.
See also this Jeff Atwood article:
http://www.codinghorror.com/blog/2008/07/the-problem-with-code-folding.html
I must admit I never used Objective-C, but of course, I used C#.
Said this, partial classes are the same thing that classes, splitting a class into multiple files doesn't make the class smaller, only splitted in file.
The usage of the class will be the same.
So I don't agree partial classes will solve that problem, they were invented mostly for other things, like, windows forms, wpf, autogenerated code.
They are useful also in other situations where classes cannot be logically splitted, but usually, should be avoided.
I think you should divide your class in several classes, a class starts to smell after 1k LOC (lines of code), also if the class is splitted in multiple files.
Use inheritance or split the class in several classes connected by fields and properties.
In the example provided by chemicalNova i would split that in several classes, not in several files.
I remember when I was a novice, we had this god class "BusinessService", or something similar. Anytime someone had locked it in TFS, you were left out of luck. So I had this brilliant idea, why don't we split it into partial classes. We ended up with something like "BusinessService1.cs" .. "BusinessService6.cs". It was a complete mess, and a complete frustration to find where things are.
I think every time you need to use partial class, it is a design mistake. If Microsoft forces you to do so (wpf, winforms, etc) - it's their design mistake.
Theres nothing wrong with splitting a class into partials. Its something that few developers take advantage of.
Personally, I like to split larger classes into partials where the business side of things for each partial have similar functionality - but only if during design time it looks like said class will become quite big. Otherwise, I split related functionality into region's.
As an example, if I am to have a "UserService" that is within a data layer, I might split it into several partials like so:
UserServiceQueries.cs
UserServiceUpdates.cs
UserServiceInserts.cs
UserServiceLogicalFunctions.cs
..however, they contain partial classes of "UserService". I don't usually use ORM's a lot, so this is perfect for me because each piece of related functionality can become quite large (obviously this is a basic example).
In closing: take advantage of what is supplied. If you're getting code smell from your class being huge.. you've only got 2 choices.. re-write it, or split it up (if it definitely needs to be this large).
My opinion anyway.
Consider a class which implements a lot of interfaces, would it make sense to implement each interface in a separate file using partial class definitions?
Would this be an abuse of the language feature or is it an idiom I'm unaware of?
If your class has to implement many interfaces, that's a reasonable way of managing the source, yes. You can edit the project file to make several of them depend on one "main" class file, which makes the Solution Explorer easier to work with.
You should ask yourself whether you shouldn't have several smaller classes each implementing a single interface though. Sometimes that will be a better approach, sometimes not - but it's always worth asking the question.
Not an idiom I have ever heard of, but sounds like an elegant way to partition your code.
I think that you should ask yourself if having a .cs file for each interface implemented by your class would make it easier or harder to understand the code. How would you name the files?
Although I might be going out on a limb here I think I'm going to suggest that you use the much hated #region directive instead if organizing the code is your goal.
You can, yes, but that won't give you any more advantages over, say, a single file with regions. Partial classes tend to be icky because it's not immediately obvious that there is another part to it, and someone else looking at the class might miss it. I personally prefer to have everything in one place.
The only benefit is to have the various interface implementations in separate physical files.
In my opinion, this is outweighed by the downside of having your class declaration located in separate physical files.
Pro: can easily pinpoint what part of a class that implement which interface (good when you are using tool that doesn't allow navigating easily through code inside the IDE).
Con: easier to lose context since now you have to navigate across multiple files
I supposed w/ the advance in IDE nowadays, it doesn't really matter. You can have a single file and let the tool help you navigate inside your class structure quickly. But then again tool can help either way... so...
Partial is still good for separating generated code vs custom code.
It makes about as much sense as having constructors in one partial class file, properties in another partial class file, etc., etc.
i.e. Don't do it unless you have a good reason.
I think there are better ways of structuring your code than using partials in this case. There's no reference in Visual Studio that you can consult to see how many partial implementations there are for a particular class so it is easy to lose track.
Depending on how much interfaces you really mean with "a lot of interfaces" you can use regions to separate the implementations. That would be fine up until 10-15 interfaces with a total of, say, 150 functions to implement. After that, things will get messy and you will lose overview.
And that's where you will benefit from other mechanisms such as inheritance, encapsulation or aggregation, and the use of services and helper classes.
But I would seriously reconsider the architecture of your code if you ever come across the need to implement 15+ interfaces....
I am recieving warning about my file by StyleCop.
Warning 1 CR0005: The file is very long at 508 lines. Please consider refactoring to make it 500 or fewer lines.
Warning 2 CR0002: Method is too long. It is 58 lines long. Consider refactoring to make it 50 or fewer lines.
How are you guys making changes to your codes? What are the best practices for this? I have no idea to divide my codes to smaller ones - being afraid of making my codes become so-complex.
So, please help ^_^ !
Nam.
You should read Martin's Fowler book "Refactoring: Improving the Design of Existing Code" and "Professional Refactoring in C# & ASP.NET" of Danijel Arsenovski.
Does the class try do to much? Could it be split into multiple smaller classes that each had a more specific and better defined purposes? If so, refactor it into multiple classes.
Could some code from the method be extracted out into it's own method to make it easier to understand? If so, do so.
Would either of the changes above make the code more difficult to understand? If so, ignore StyleCop. Remember, it's just a generic tool to help make your code easier to read. There will almost certainly be at least some recommendations that won't make sense for your circumstances.
I'd suppress the warnings and worry about more important things.
I'm not sure it makes sense to impose such an arbitrary limit on the size of a file or method. It's not so much the numbers 50 & 500 themselves, but the fact that there is such a number. Where does it come from? Why is 50 lines considered readable, but 58 isn't?
As demonstrated here, concentrating on these metrics can be counter productive, and draw attention away from real issues. Perhaps time might be better spent, and good design principles better served, ensuring something like proper separation of concerns, for example. Split your lines and methods according to what should logically go in them, rather than breaking them up to meet arbitrary size criteria.
Well, the 'Extract Method' refactoring is very useful for making methods shorter (by putting them into another method), which I believe is in 2010. (Highlight some code, right click and it should be in the menu somewhere).
The best way to break a file up (assuming you only have one class in it) is to extract some of the functionality into another class. Google 'Extract Class' and you'll find some info on it.
Like #Justin says, doing this might seem more complex at first because there are more files/methods to deal with, but because each file/method is smaller, there's less to deal with at any one time. Some (respected) people take this really far. It takes a little getting used to but you code will be (arguably) better for it.
Others have mentioned refactoring, and also focusing on breaking the class down to do just 1x responsibility (part of the S.O.L.I.D. rules for OOP). However; if your class is still 500x lines, and performing one responsibility, then you're not in too terrible a position.
If your code-file contains XML documentation and white-spaces, then 500x lines is only slightly large (and that's dependent on what it does). Many of my "simple" classes end up around 350 lines once completed. Smaller is better, but concise is really what you want.
Another good book for understanding how your code should look is Robert C. Martin's Clean Code. It lays down many good rules in designing well thought-out classes and methods.
It is possible to split the definition of a class or a struct, or an interface over two or more source files. Each source file contains a section of the class definition, and all parts are combined when the application is compiled. For example here the 'bar' class is split between foo1.cs and foo2.cs.
foo1.cs
public partial class Bar
{
public void bat()
{
}
}
foo2.cs
public partial class Bar
{
public void baz()
{
}
}
For more information on this see Partial Class Definitions (C# Programming Guide)
This is not a rule that ships with StyleCop. Is it something your company developed in house? I'm curious about the rationale behind the rule. 500 lines seems like a pretty strict limitation.
Never sure where to place functions like:
String PrettyPhone( String phoneNumber ) // return formatted (999) 999-9999
String EscapeInput( String inputString ) // gets rid of SQL-escapes like '
I create a Toolbox class for each application that serves as a repository for functions that don't neatly fit into another class. I've read that such classes are bad programming practice, specifically bad Object Oriented Design. However, said references seem more the opinion of individual designers and developers more than an over-arching consensus. So my question is, Is a catch-all Toolbox a poor design pattern? If so, why, and what alternative is there?
Great question. I always find that any sufficiently complex project require "utility" classes. I think this is simply because the nature of object-oriented programming forces us to place things in a neatly structured hierarchical taxonomy, when this isn't always feasible or appropriate (e.g. try creating an object model for mammals, and then squeeze the platypus in). This is the problem which motivates work into aspect oriented programming (c.f. cross cutting concern). Often what goes into a utility class are things that are cross-cutting concerns.
One alternative to using toolbox or utility classes, are to use extension methods to provide additional needed functionality to primitive types. However, the jury is still out on whether or not that constitutes good software design.
My final word on the subject is: go with it if you need, just make sure that you aren't short-cutting better designs. Of course, you can always refactor later on if you need to.
I think a static helper class is the first thing that comes to mind. It is so common that some even refer to it as part of the object-oriented design. However, the biggest problem with helper classes is that they tend to become a large dump. I think i saw this happen on a few of the larger projects i was involved in. You're working on a class and don't know where to stick this and that function so you put it in your helper class. At which point your helpers don't communicate well what they do. The name 'helper' or 'util' itself in the class name doesn't mean anything. I think nearly all OO gurus advocate against helpers since you can very easily replace them with more descriptive classes if you give it enough thought. I tend to agree with this approach as I believe that helpers violate the single responsibility principle. Honestly, take this with a grain of salt. I'm a little opinionated on OOP :)
In these examples I would be more inclined to extend String:
class PhoneNumber extends String
{
public override string ToString()
{
// return (999) 999-9999
}
}
If you write down all the places you need these functions you can figure out what actually uses it and then add it to the appropriate class. That can sometimes be difficult but still something you should aim for.
EDIT:
As pointed out below, you cannot override String in C#. The point I was trying to make is that this operation is made on a phone number so that is where the function belongs:
interface PhoneNumber
{
string Formatted();
}
If you have different formats you can interchange implementations of PhoneNumber without littering your code with if statements, e.g.,
Instead of:
if(country == Countries.UK) output = Toolbox.PhoneNumberUK(phoneNumber);
else ph = Toolbox.PhoneNumberUS(phoneNumber);
You can just use:
output = phoneNumber.Formatted();
There is nothing wrong with this. One thing is try to break it up into logical parts. By doing this you can keep your intellisense clean.
MyCore.Extensions.Formatting.People
MyCore.Extensions.Formatting.Xml
MyCore.Extensions.Formatting.Html
My experience has been that utility functions seldom occur in isolation. If you need a method for formatting telephone numbers, then you will also need one for validating phone numbers, and parsing phone numbers. Following the YAGNI principle, you certainly wouldn't want to write such things until they're actually needed, but I think it's helpful to just go ahead and separate such functionality into individual classes. The growth of those classes from single methods into minor subsystems will then happen naturally over time. I have found this to be the easiest way to keep the code organized, understandable, and maintainable over the long term.
When I create an application, I typically create a static class that contains static methods and properties that I can't figure out where to put anywhere else.
It's not an especially good design, but that's sort of the point: it gives me a place to localize a whole class of design decisions that I haven't thought out yet. Generally as the application grows and is refined through refactoring, it becomes clearer where these methods and properties actually ought to reside. Mercifully, the state of refactoring tools is such that those changes are usually not exceptionally painful to make.
I've tried doing it the other way, but the other way is basically implementing an object model before I know enough about my application to design the object model properly. If I do that, I spend a fair amount of time and energy coming up with a mediocre solution that I have to revisit and rebuild from the ground up at some point in the future. Well, okay, if I know I'm going to be refactoring this code, how about I skip the step of designing and building the unnecessarily complicated classes that don't really work?
For instance, I've built an application that is being used by multiple customers. I figured out pretty early on that I needed to have a way of separating out methods that need to work differently for different customers. I built a static utility method that I could call at any point in the program where I needed to call a customized method, and stuck it in my static class.
This worked fine for months. But there came a point at which it was just beginning to look ugly. And so I decided to refactor it out into its own class. And as I went through my code looking at all the places where this method was being called, it became extremely clear that all of the customized methods really needed to be members of an abstract class, the customers' assemblies needed to contain a single derived class that implements all of the abstract methods, and then the program just needed to get the name of the assembly and the namespace out of its configuration and create an instance of the custom features class at startup. It was really simple for me to find all of the methods that had to be customized, since all I needed to do was find every place that my load-a-custom-feature method was being called. It took me the better part of an afternoon to go through the entire codebase and rationalize this design, and the end result is really flexible and robust and solves the right problem.
The thing is, when I first implemented that method (actually it was three or four interrelated methods), I recognized that it wasn't the right answer. But I didn't know enough to decide what the right answer was. So I went with the simplest wrong answer until the right answer became clear.
I think the reason it's frowned upon is because the "toolbox" can grow and you will be loading a ton of resources every time you want to call a single function.
It's also more elegant to have the methods that apply to the objects in the actual class - just makes more sense.
That being said, I personally don't think it's a problem, but would avoid it simply for the reasons above.
I posted a comment, but thought I'd elaborate a bit more.
What I do is create a Common library with namespaces: [Organisation].[Product].Common as the root and a sub namespace Helpers.
A few people on here mention things like creating a class and shoving some stuff they don't know where else to put in there. Wrong. I'd say, even if you need one helper method, it is related to something, so create a properly named (IoHelper, StringHelper, etc.) static helper class and put it in the Helpers namespace. That way, you get some structure and you get some sort of separation of concerns.
In the root namespace, you can use instance utility classes that do require state (they exist!). And needless to say also use an appropriate class name, but don't suffix with Helper.