I have a class that can be called either from a GUI or form a Non-Graphical Environment (Batch mode)
What is the most convenient an best practice way to "tell" the GUI-related parts of the code NOT to execute when executed in batch mode.
I think of something like
public MyMethod()
{
[#TAG: DOTHIS_ONLY_IF_GUIMODE]
ShowPanels();
....
}
And the GUI_MODE_ACTIVATED would be set to true or false on runtime somewhere, depending on where the program is called from
I want to avoid the ugly tracing if/else stuff scattered all over my code.
My little thumb tells me AOP is the way to go (but if I manage to find a simpler alternative I'll go for it)So, what is the SIMPLEST and most straightforward way to do this ?
Update:
As most contributors pointed out, separating GUI Code from Business code is a rule of thumb, But I am still interested in knowing ways to do this even if NO GUI is involved (ie, two different BATCH modes for two different environments, for example)
I think your best bet is to take the GUI-specific code out of the class and implement events triggered at key times in the class's processing. When called by the GUI, the GUI code subscribes to those events and 'does the right thing.' The batch-code ignores the events and all is well.
What is the most convenient an best practice way to "tell" the GUI-related parts of the code NOT to execute when executed in batch mode.
This is why you separate business logic concerns from UI concerns.
So, what is the SIMPLEST and most straightforward way to do this ?
Separate business logic concerns from UI concerns.
The simplest and most straightforward way is to use an if statement.
A less straightforward, but more structured, way would be to make the ShowPanels method abstract, then derive two classes: one for GUI mode and one for batch mode.
Add Aspects to Object Using Dynamic Decorator
.
Your classs should concern only business logic not presentation (GUI or Batch, etc.). At runtime, you can attach presentation (GUI or non-GUI) code to objects of the class as needed.
No need to have the ugly attribute code in your class definition.
Related
Are there any disadvantages in using a private accessor to test a piece of code?
I'm weighing the option of using a private accessor only to test my GUI, as opposed the the methods/properties that are publically exposed.
This will allow some GUI testing i need, i just wanted to make sure their were not any hidden "pitfalls" in using a private accessor in how it behaves.
So to recap, your stated goal is:
I'm weighing the option of using a private accessor only to test my GUI... This will allow some GUI testing i need...
In short, yes there are pitfalls. The code you are testing is still tightly coupled to the user interface.
In the comments you clarify your goal/problem as:
What about in the case if i want to test, Drag/drop. Custom Controls, Overriden events?
All I can say is welcome aboard. The software industry has struggled with this for nearly half a century. The fact remains that testing UI is hard, Really HARD. Yes you can take a piece of code that is tightly coupled with a UI element and try and automate it; however, your going to be fighting tooth-and-nail to make headway against poor assumptions.
The 'trick' to testable UI is not to make your UI testable, but to remove the code you want to test from the UI. Thus the wide acceptance of N-Tier application development and presentation design patterns like MVC, MVVM, etc.
see the following:
Model View Controller
Model View ViewModel
Model–view–adapter
Model–view–presenter
The primary goal or driving force behind many of these design patterns is to remove the tight coupling between behavior and presentation. This enables you to then test a behavior like drag-n-drop without a user interface. My recommendation is review the patterns, choose one you like, and then start refactoring the code as you write your unit tests.
Another way to think of writing UI for testing is to remove every if, else, for, while, switch, or other control statement from your user interface code. The resulting 'shell' of a UI should be very resilient to change. Just be careful when using things like data binding that rely on reflection (which is generally an acceptable practice). The primary downside to this is that the compiler can not tell you that a member no longer exists.
Updated
#timmy you wrote:
... for example if i want to test mouse click behavior...
So what about the mouse click behavior cannot be moved to a controller rather than being embedded into the form? I guess the "Close" button might have a problem, but beyond that why not move the logic to another class that can then be tested?
BTW, You don't have to pick just one pattern MVC, MVVM, etc, they are 'guidelines' or 'suggestions' not hard rules so don't get ridiculous with it. Just try and make the logic separate from the UI and independently testable. As an example, perhaps your "Click" event fits better with a simple command class? Using a command pattern is easy, new up an object and execute it. Consider this example code for a folder copy form:
private void OnCopyClick(object sender, EventArgs args)
{
var cmd = new MyCopyCommand(this.FolderPath, this.txtTargetFolderPath.Text);
new ErrorHandler(this).Perform(cmd);
}
This works well, it has no 'real' logic other than what to provide the command and has no conditional code paths. Notice we don't even directly invoke the command but rather defer that to someone who can handle an error appropriately. Usually this 'ErrorHandler' would be provided to the Form rather than constructed directly, but you get the idea.
From this we should be easily able to verify the correct behavior of the MyCopyCommand. In the end you should wind up with a bunch of "flat functions" in the UI, ie. functions that have no nesting or curly braces. Of course this is a rule of thumb, not to be taken to such an extreme as to prevent you from being productive.
I know this may seem like a lot of work, but truthfully it is not when you are already working to write a set of tests. You can be productive AND write solid code. You just need to know when to cheat, and when not to. That comes with experience and after 20 years, 10 of those writing NUnits, I still fail once in a while. When something breaks because you didn't do this, first extract the logic from the UI, then write a unit test to prove it's broken, then fix it.
It's better not to use them, instead try to find out if you can inject any dependency. Unless you're working on a legacy code where you want to create some unit tests using private accessors, I'd suggest not to use them and even in this case, I'd recommend you do that temporarily until you refactor legacy code.
In addition to what AD.NET said.
I could use those private properties in tests only until I finish my refactoring (to Model View Controller, Model View Presenter, Model View ViewModel) so that I don't have to test GUI at all!
Lately I've been trying to follow the TDD methodology, and this results in lot of subclasses so that one can easily mock dependencies, etc.
For example, I could have say a RecurringProfile which in turn has methods / operations which can be applied to it like MarkAsCancel, RenewProfile, MarkAsExpired, etc.. Due to TDD, these are implemented as 'small' classes, like MarkAsCancelService, etc.
Does it make sense to create a 'facade' (singleton) for the various methods/operations which can be performed on say a RecurringProfile, for example having a class RecurringProfileFacade. This would then contain methods, which delegate code to the actual sub-classes, eg.:
public class RecurringProfileFacade
{
public void MarkAsCancelled(IRecurringProfile profile)
{
MarkAsCancelledService service = new MarkAsCancelledService();
service.MarkAsCancelled(profile);
}
public void RenewProfile(IRecurringProfile profile)
{
RenewProfileService service = new RenewProfileService();
service.Renew(profile);
}
...
}
Note that the above code is not actual code, and the actual code would use constructor-injected dependencies. The idea behind this is that the consumer of such code would not need to know the inner details about which classes/sub-classes they need to call, but just access the respective 'Facade'.
First of all, is this the 'Facade' pattern, or is it some other form of design pattern?
The other question which would follow if the above makes sense is - would you do unit-tests on such methods, considering that they do not have any particular business logic function?
I would only create a facade like this if you intend to expose your code to others as a library. You can create a facade which is the interface everyone else uses.
This will give you some capability later to change the implementation.
If this is not the case, then what purpose does this facade provide? If a piece of code wants to call one method on the facade, it will have a dependency on the entire facade. Best to keep dependencies small, and so calling code would be better with a dependency on MarkAsCancelledService tha one on RecurringProfileFacade.
In my opinion, this is kind of the facade pattern since you are abstracting your services behind simple methods, though a facade pattern usually has more logic I think behind their methods. The reason is because the purpose of a facade pattern is to offer a simplified interface on a larger body of code.
As for your second question, I always unit test everything. Though, in your case, it depends, does it change the state of your project when you cancel or renew a profile ? Because you could assert that the state did change as you expected.
If your design "tells" you that you could use a Singleton to do some work for you, then it's probably bad design. TDD should lead you far away from thinking about using singletons.
Reasons on why it's a bad idea (or can be an ok one) can be found on wikipedia
My answer to your questions is: Look at other patterns! For example UnitOfWork and Strategy, Mediator and try to acheive the same functionality with these patterns and you'll be able to compare the benefits from each one. You'll probably end up with a UnitOfStrategicMediationFacade or something ;-)
Consider posting this questions over at Code Review for more in depth analysis.
When facing that kind of issue, I usually try to reason from a YAGNI/KISS perspective :
Do you need MarkAsCancelService, MarkAsExpiredService and the like in the first place ? Wouldn't these operations have a better home in RecurringProfile itself ?
You say these services are byproducts of your TDD process but TDD 1. doesn't mean stripping business entities of all logic and 2. if you do externalize some logic, it doesn't have to go into a Service. If you can't come up with a better name than [BehaviorName]Service for your extracted class, it's often a sign that you should stop and reconsider whether the behavior should really be extracted.
In short, your objects should remain cohesive, which means they shouldn't encapsulate too many responsibilities, but not become anemic either.
Assuming these services are justified, do you really need a Facade for them ? If it's only a convenient shortcut for developers, is it worth the additional maintenance (a change in one of the services will generate a change in the facade) ? Wouldn't it be simpler if each consumer of one of the services knows how to leverage that service directly ?
The other question which would follow if the above makes sense is -
would you do unit-tests on such methods, considering that they do not
have any particular business logic function?
Unit testing boilerplate code can be a real pain indeed. Some will take that pain, others consider it not worthy. Due to the repetitive and predictable nature of such code, one good compromise is to generate your tests automatically, or even better, all your boilerplate code automatically.
general consensus
I've done quite a lot of reading up on the subject of testing complex classes and private methods.
The general consensus seems to be:
"if you need to test private methods then you're class is badly designed"
"if your class is complex, then you need to separate it out"
So, I need your help.
the problem Class
So I have a relatively simple class whose long running job it is to:
poll a datasource
do some very simple mapping of the data
send that data somewhere else
Aditionally:
it needs to be able to be quite fault tolerant by being able to retry various tasks in case of certain errors.
the testing problem
The point of the class is to abstract a lot of the fault tolerance and threading... basically by using a simple Timer Class and some internal lists to keep track of errors etc.
Because of the Timer, certain methods are called on different threads asynchronously... additionally a bunch of the methods rely on global private fields.
How should I test this class... particularly because so many methods are private?
cheers guys
I would extract the code to poll the data into a separate class that can be mocked, and also extract the code that sends that data for the same reason. You might want to extract the data mapping code, depending on how trivial it is.
I would definitely use mock timers in the unit tests, otherwise your tests are hard to set up and slow to run. You can either pass in the timer in the constructor, or expose a property that you can set. I often create a regular timer in the constructor and then overwrite that from my unit test.
You might also be able to extract the retry logic so that it can be tested separately from the other code. Passing in a delegate of the code to try and retry might be a way to decouple the data code from the retry logic. You can also use IEnumerable and the yield statement to generate your data and feed it to the retry code. Essentially, I'm looking for ways to make it so that the retry code doesn't directly call the target code that it's supposed to try and retry. That makes it easier to test and generate all possible errors for, although you can get some of the same benefits by just mocking out that target code.
If you really have multithreaded scenarios that you need to test, there are some tools out there to coordinate threads from within a test. One of them is a port I created of Java MultithreadedTC called TickingTest.
You could try using something like JMock. This will let you replace the real Timer with a mock Timer that you can control. You can then set up test cases that fire method calls in a defined order, and you can also set up error conditions by creating a mock data source.
EDIT: Whoops! Didn't see the C# tag. Maybe there's a C# equivalent to JMock.
Today I had an epiphany, and it was that I was doing everything wrong. Some history: I inherited a C# application, which was really just a collection of static methods, a completely procedural mess of C# code. I refactored this the best I knew at the time, bringing in lots of post-college OOP knowledge. To make a long story short, many of the entities in code have turned out to be Singletons.
Today I realized I needed 3 new classes, which would each follow the same Singleton pattern to match the rest of the software. If I keep tumbling down this slippery slope, eventually every class in my application will be Singleton, which will really be no logically different from the original group of static methods.
I need help on rethinking this. I know about Dependency Injection, and that would generally be the strategy to use in breaking the Singleton curse. However, I have a few specific questions related to this refactoring, and all about best practices for doing so.
How acceptable is the use of static variables to encapsulate configuration information? I have a brain block on using static, and I think it is due to an early OO class in college where the professor said static was bad. But, should I have to reconfigure the class every time I access it? When accessing hardware, is it ok to leave a static pointer to the addresses and variables needed, or should I continually perform Open() and Close() operations?
Right now I have a single method acting as the controller. Specifically, I continually poll several external instruments (via hardware drivers) for data. Should this type of controller be the way to go, or should I spawn separate threads for each instrument at the program's startup? If the latter, how do I make this object oriented? Should I create classes called InstrumentAListener and InstrumentBListener? Or is there some standard way to approach this?
Is there a better way to do global configuration? Right now I simply have Configuration.Instance.Foo sprinkled liberally throughout the code. Almost every class uses it, so perhaps keeping it as a Singleton makes sense. Any thoughts?
A lot of my classes are things like SerialPortWriter or DataFileWriter, which must sit around waiting for this data to stream in. Since they are active the entire time, how should I arrange these in order to listen for the events generated when data comes in?
Any other resources, books, or comments about how to get away from Singletons and other pattern overuse would be helpful.
Alright, here's my best shot at attacking this question:
(1) Statics
The Problem with static that you may be having is that it means different things in .NET and say, C++. Static basically means it's accessible on the class itself. As for it's acceptability id say it's more of something you'd use to do non-instance specific operations on a class. Or just general things like Math.Abs(...). What you should use for a global config is probably a statically accessed property for holding the current/active configuration. Also maybe some static classes for loading/saving setting the config, however the config should be an Object so it can be passed around manipulated, etc.
public class MyConfiguration
{
public const string DefaultConfigPath = "./config.xml";
protected static MyConfiguration _current;
public static MyConfiguration Current
{
get
{
if (_current == null)
Load(DefaultConfigPath);
return _current;
}
}
public static MyConfiguration Load(string path)
{
// Do your loading here
_current = loadedConfig;
return loadedConfig;
}
// Static save function
//*********** Non-Static Members *********//
public string MyVariable { get; set; }
// etc..
}
(2) Controller/Hardware
You should probably look into a reactive approach, IObserver<> or IObservable<>, it's part of the Reactive Framework (Rx).
Another approach is using a ThreadPool to schedule your polling tasks, as you may get a large number of threads if you have a lot of hardware to pool. Please make sure before using any kind of Threading to learn a lot about it. It's very easy to make mistakes you may not even realize. This Book is an excelent source and will teach you lots.
Either way you should probably build services (just a name really) for managing your hardware which are responsible for collecting information about a service (essentially a model-pattern). From there your central controller can use them to access the data keeping the program logic in the controller, and the hardware logic in the service.
(3) Global Configuration
I may have touched this subject in point #1 but generally that's where we go, if you find yourself typing too much you can always pull it out of there assuming the .Instance is an object.
MyConfiguration cfg = MyConfiguration.Current
cfg.Foo // etc...
(4) Listening For data
Again the reactive framework could help you out, or you could build up an event-driven model that uses triggers for incoming data. This will make sure you're not blocking on a thread till data comes in. It can reduce the complexity of your application greatly.
for starters, you can limit use of singleton through the "Registry" pattern, which effectively means you have one singleton which allows you to get to a bunch of other preconfigured objects.
This is not a "fix" but an improvement, it makes the many objects that are singletons a little more normal and testable. eg... (totally contrived example)
HardwareRegistry.SerialPorts.Serial1.Send("blah");
but the real problem seems to be you are struggling with making a set of objects that work nicely together. There's two kind of steps in OO.... configuring objects, and letting objects do their thing.
so perhaps look at how you can configure non singleton objects to work together, and then hang that off a registry.
Static :-
Plenty of exceptions to the rules here, but in general, avoid it, but it is useful for doing singletons, and creating methods that do "general" computing outside the context of an object. ( like Math.Min )
Data Monitoring :-
its often better to do as you hint at, create a thread with a bunch of preconfigured objects that will do your monitoring. Use message passing to communicate between threads (through a thread safe queue) to limit thread locking problems. Use the registry pattern to access hardware resources.
you want something like a InstrumentListner that uses an InstrumentProtocol (which you subclass for each protocol) to I dunno, LogData. The command pattern may be of use here.
Configuration:-
have your configuration information and use something like the "builder" pattern to translate your configuration into a set of objects set up in a particular way. ie, don't make your classes aware of configuation, make a object that configures objects in a particular way.
Serial Ports :-
I do a bunch of work with these, what I have is a serial connection, which generates a stream of characters which it posts as an event. Then I have something that interprets the protocol stream into meaningful commands. My protocol classes work with a generic "IConnection" of which a SerialConnection inherits..... I also have TcpConnections, MockConnections, etc, to be able to inject test data, or pipe serial ports from one computer to another, etc. So Protocol classes just interpret a stream, have a statemachine, and dispatch commands. The protocol is preconfigured with a Connection, Various things get registered with the protocol, so when it has meaningful data they will be triggered and do their thing. All this is built from a configuration at the beginning, or rebuilt on the fly if something changes.
Since you know about Dependency Injection, have you considered using an IoC container to manage lifetimes? See my answer to a question on static classes.
You (the OP) seem preoccupied with OO design, well, I'll put it this way when thinking about the static variables things. The core concept is encapsulation and reuse; somethings you could care less about reusing but you almost always want the encapsulation. If it's a static variable, it's not really encapsulated, is it? Think about who needs to access it, why, and how far you can HIDE it from client code. Good designs often can change their internals without much breakage to clients, that is what you want to think about. I agree with Scott Meyers (Effective C++) about many things. OOP goes way beyond the class keyword. If you've never heard of it it, look up properties: yes they can be static, and C# has a very good way of using them. As opposed to literally using a static variable. Like I hinted at the start of this list item: think about how not to shoot yourself in the foot later as the class changes with time, that's something many programmers fail to do when designing classes.
Take a look at that Rx framework someone mentioned. The threading model to use, for such a situation as you described, is not readily decidable without more specifics about the use case IMHO. Be sure you know what you're doing with threads. A lot of people can't figure out threads to save their lives; it's no that hard, being tread safe can be when (re)using code. Remember controllers should often be separate from the objects they are controlling (E.g. not the same class); if you don't know it, look up a book on MVC and buy gang of four.
Depends on what you need. For many applications a class that is almost entirely filled with static data, is good enough; like a singleton for free. It can be done very OO. Sometimes you would rather have multiple instances or play with injection, that makes it more complex.
I suggest threads and events. The ease of making code event driven is actually one of the nicer things about C# IMHO.
Hmm, killing off singletons...
In my experience, a lot of the more common uses that young programmers put singletons to, are little more than a waste of the class keyword. Namely something they meant as a stateful module being rolled into a highlander class; and there are some bad singleton implementations out there to match. Whether this is because they failed to learn what they're doing, or only had Java in college, I dunno. Back in C land, it's called a using data at file scope and exposing an API. In C# (and Java) you're kind of bound to it being a class more than many languages. OOP != class keyword; learn the lhs well.
A decently written class can use static data to effectively implement a singleton, and make the compiler do the leg work of keeping it one, or as one as you are ever going to get of anything. Do NOT replace singletons with inheritance unless you seriously know what the heck you are doing. Poorly done inheritance of such things, leads to more brittle code that knows waaaay to much. Classes should be dumb, data is smart. That sounds stupid unless you look at the statement deeply. Using inheritance IMHO for such a thing, is generally a bad thing(tm), languages have the concept of modules/packages for a reason.
If you are up for it, hey you did convert it to singletons ages ago right? Sit down and think a bit: how can I best structure this app, in order to make it work XXX way, then think how doing it XXX way impacts things, for example is doing this one way going to be a source of contention among threads? You can go over a lot of things in an hour like that. When you get older, you'll learn better techniques.
Here is one suggestion for an XXX way to start with: (visualize) write(^Hing) a composite controller class, that works as a manager over the objects it references. Those objects were your singletons, not the the controller holds them, and they are but instances of those classes. This isn't the best design for a lot of applications (particularly can be an issue in heavily threaded ones IMHO), but it will generally solve what causes most younglings to reach for a singleton, and it will perform suitably for a vast array of programs. It's uh, like design pattern CS 102. Forget the singleton you learned in CS 607.
That controlling class, perhaps "Application' would be a more apt ;), basically solves your need for singletons and for storing configuration. How to do it in a sublimely OO way (assuming you do understand OOP) and not shoot yourself in the foot (again), is an exercise for your own education.
If it shows, I am not a fan of the so called singleton pattern, particularly how it is often misused. Moving a code base away from it, often depends on how much refactoring you are prepared to use. Singletons are like global variables: convenient but not butter. Hmm, I think I'll put that in my quotations file, has a nice phrase to it...
Honestly, you know more about the code base and the application in question then anyone here. So no one can really design it for you, and advice speaks less then action, at least where I come from.
I limit myself to at most two singletons in an application / process. One is usually called SysConfig and houses things that might otherwise end up as global variables or other corrupt concepts. I don't have a name for the second one since, so far, I've never actually reached my limit. :-)
Static member variables have their uses but I view them as I view proctologists. A lifesaver when you need one but the odds should be a "million to one" (Seinfeld reference) that you can't find a better way to solve the problem.
Create a base instrument class that implements a threaded listener. Derived classes of that would have instrument specific drivers, etc. Instantiate a derived class for each instrument then store the object in a container of some sort. At cleanup time just iterate through the container. Each instrument instance should be constructed by passing it some registration information on where to send its output/status/whatever. Use your imagination here. The OO stuff gets quite powerful.
I recently had to tackle a similar problem, and what I did seemed to work well for me, maybe it will help you:
(1) Group all "global" information into a single class. Let's call it Configuration.
(2) For all classes which used to use these static objects, change them to (ultimately) inherit from a new abstract base class which looks something like
abstract class MyBaseClass {
protected Configuration config; // You can also wrap it in a property
public MyBaseClass(Configuration config) {
this.config = config;
}
}
(3) Change all constructors of classes deriving from MyBaseClass accordingly. Then just create one instance of Configuration at start and pass it on everywhere.
Cons:
You need to refactor many of your constructors and every place in which they are called
This won't work well if you do not derive your top-level classes from Object. Well, you can add the config field to the derived class, it's just less elegant.
Pros
Not a lot of effort to just change inheritance and constructors, and bang - you can switch all Configuration.Instance with config.
You get rid of static variables completely; so no problems now if, for example, your application suddenly turns into a library and someone is trying to invoke multiple methods concurrently or whatever.
Great question. A few quick thoughts from me...
static in C# should only be used for data that is exactly the same for all instances of a given class. Since you're currently stuck in Singleton hell you only have one instance of everything anyways, but once you break out of that this is the general rule (at least, it is for me). If you start threading your classes you may want to back off on static usage because then you have potential concurrency issues, but that's something that can be tackled later.
I'm not sure how your hardware actually works, but assuming that there's some basic functionality that's the same across all of them (like, how you interface with them at a raw data level or similar) then this is a perfect instance to create a class hierarchy. The base class implements the low level / similar stuff with virtual methods for descendant classes to override to actually properly interpret the data / feed it onward / whatever.
Good luck.
What is the best way to write the code ?
(1) Like directly writing the code in the button_click() event.
or
(2) Make the function of that code which I write in button_click() event and write this function in one class and then that function I should call in the button_Click() event.Like is it called three-tier approach to write the code ?
Like in button_Click() event I write the code to save the records in csv file from datatable.So I should write that code in button_Click() event or I should make one new function and one new class and write that code in that function which is the new class and calling that function in button_Click() event.
This is only one example but I am talking about all the code written in my application that which is the appropriate and best way to write the code and what are the benefits ? Note that I write the code in Winforms with c#.
You should go for the separate function in a different class. You should do that because you'll make the code reusable and create a decent separation between the user interface and application logic. Like this, you could for example change the UI without affecting the rest of the application.
Also take a look at MVC pattern, you'll understand better the whole idea.
The only situation where i think that the first option should be used is when it does some action that will affect the UI, and still i'll create this in a separate function inside the Form class.
If it's affecting the UI, it should be in the same class because it's related and for example if it's a code to refresh a grid i'll put this in a separate method inside the same Form class because this could be used in different places inside it. So changing the UI has no impact on the application, you just make your code reusable & maintainable.
It all depends on situation.
If you are going to make updates to the Form, then it's better to have the updating code in the Form. However, if there are lots of processing, then surely it's better design to have a separate class handle the job.
It all depends on situation.
Generally, you don't want any logic in the event handler, since GUIs tend to provide redundant mechanisms (context menu, menu bar, toolbar, accelerator key) for triggering the same command, and the event signatures aren't compatible for all of these. Then the question becomes whether your common function should go in the Form class or into the data model.
I often start out with the logic in the Form and then refactor it into model classes as needed. Many small apps will never get large enough that multiple classes are required for maintainability. As long as you avoid code duplication (i.e. copy+paste) then refactoring will be straightforward later if you find you need it.
It is always good to develop classes for jobs. As it makes your code reusable and it also implement three tier Architecture. The benefit is that it is easy to understand.
The important thing is that, it is only beneficial if you develop your classes appropriately. Develop methods in the class which can be reusable for you.
The another benefit is that it hides the complexity of your code.
There are two general approaches to adding structure to code: top down and bottom up. Top down structure comes from design work that can involve a formal or informal process and pure design artifacts like UML diagrams or functional specs. The ultimate goal in a top down process is to create classes and interfaces in your code that will provide appropriate structure to make your code maintainable. This can happen before you write the code, or as part of an iteration, but the idea is that you create the structure first, then create the code.
Bottom up structure comes from refactoring. For example, start with all your logic in a button click. When you add a menu item that does the same thing as the button click, move the code for your button click function into a private member function on the form. When you need the same features in a different part of the application, encapsulate the code and state variables used by your private member function into a class.
I'd recommend using both approaches. The right mix for your situation depends on the development team (size, location, ability to communicate) and the size of your application. Generally speaking, large applications require more top down, and on very small applications a minimal amount of top down design is adequate. But there should always be some high level planning, even for a small app.