Form object question - c#

Does anyone have any hard and fast rules about what kind of code the form object should handle as opposed to letting the object itself handle it? For example, if there is a race, should the object that is racing say, horses, handle the race as part of being a horse, or is it better to place that inside the form object? I guess what I'm asking is how one decides what goes into an object like a horse as say a method, and what goes into a form object instead of a horse. Are there any rules you use to figure out where code is best abstracted in this case?

This is called "separation of concerns". Let the form handle the display and user interaction. Let the Racer handle racing.

I try to develop my software so that core functionality that is not UI dependent is abstracted into classes that bear responsibility for their tasks.
Try to think:
How could I write this so I could have both a GUI interface and a console interface without duplicating any code.
The UI should only handle visuals & user interaction. Everything else should be organized based on its role.

Not sure there is absolutely a right answer here. But agreed with John Saunders. A "Form's" job is primarily responsible to display data to the user and accept data input. The closer you keep it to that, and that alone. Think about when there's another place for this type of data to be used, if the code is elsewhere, it can be reused.
Have a "Business Object" or a "Facade" handle the logic of the race, and the form to display it.

Try to represent things the way they are in the real world. Anything that describes the properties or actions of a horse, belongs in a horse object. Anything that describes the properties or actions of a race (including, perhaps, a collection of horse objects), belongs in a race object. A form is not a real world object, but just a gadget for displaying information from horses/races/whatever. So don't store anything with the form except as needed to present the real data on the screen.

Since the form is part of the UI I would apply my UI hard and fast rule:
UI = formating, sorting and displaying data plus accepting and verifying input

Related

What exactly is encapsulation?

My teacher told me that encapsulation is data/information hiding.
But what I understand from here is that Encapsulation is bundling data and methods that act on that data into one unit. And that [encapsulation] allows us to create information hiding mechanisms. Like, making a variable read-only, or making it accessible through some checkpoints.
Am I right that encapsulation in itself is not data hiding, but a way through which we can hide data?
There is no authoritative source that can tell you with full confidence. You (we all) have to ask unfortunately every time it comes up what exactly the speaker/writer means.
Most of the time is encapsulation a little bit more than information hiding.
Encapsulation is a bit more abstract, and may refer to not just data, but logic or any knowledge in general.
Data hiding is just that (normally), hiding the data (the instance variables).
How these things get implemented is a source of even more debate! For example some (if not most) people refer to data hiding when instance variables are simply declared private. Even if there is a public getter for that same data! (the linked article seem to support this position)
Again for others (myself included) calling data hidden when there is a public getter for it sounds strange to say the least.
Some people insist that getters are ok (the data hiding applies) if the returned data is immutable, since it can not be changed.
Encapsulation is often used together with logic. For example: I encapsulate how to send emails in this class, etc.
The problem is, everyone uses the same words, so it's nigh impossible to tell what someone really means by either of these things. If you want to know what someone is talking about, always demand an example (or two).
I will give an explanation to encapsulation and data hiding as I understood from code complete book
When you create a class/method the primary goal is to reduce complexity of your program. You create a class/method to hide information so that you won’t need to think about it. Sure, you’ll need to think about it when you write the class/method. But after it’s written, you should be able to forget the details and use the class/method without any knowledge of its internal workings.
So each class/method should ask a question "What should I hide in order to reduce complexity?" and hence you start to create the interface that this class/method provides to the outside world (other classes/methods). This consists of creating a good abstraction for the interface to represent and ensuring that the details remain hidden behind the abstraction.
Abstraction helps to manage complexity by providing models that allow you to ignore implementation details. Encapsulation is the enforcer that prevents you from looking at the details even if you want to. If I declare a method as private, I'm forcing that it should be used only inside the class and not from outside and if I declare it as public I'm saying that it is part of the interface this class is providing and it can be used from outside. The two concepts are related because, without encapsulation, abstraction tends to break down.
It means you can't mess with the other object's innards unless that object lets you. It is encapsulated, in a capsule you can't get into. An artifact of this is hiding information. If you are closed up, and only you can open things up, then you've pretty much hidden everything inside of yourself. Thus, the hiding is a consequence of encapsulating.
Think of a Birthday class that takes in a Birthdate (DateTime) in the constructor.
It has properties the following that are filled
Public Property _ZodiacSign As String = String.Empty
Public Property _ChineseZodiac As String = String.Empty
Public Property _ChineseZodiacChar As String = String.Empty
Public Property _is21AndOver As Boolean
Public Property _ChineseDate As String
Public Property _EstimatesConvievedDate As DateTime
You have no idea what the logic is to figure out the zodiac sign or chinesezodiac or are they over 21, it is a black box.

MVVM, ViewModel, Model & MessageBoxes

I understood the basic priinciple of not calling the MessageBox in the ViewModel code or the Model code but instead use a callback of some kind, be it an interface or a func declaration that is added to the ViewModel upon construction.
So far, so good.
But the examples given only go so far that you press a button in the View and then the ViewModel raises the MessageBox via callback to confirm and then continues.
But what if the Model is doing tons of stuff first before realizing the need for a user feedback? Do I give the model also the callback function to work?
Does it have to be designed differently?
Any advice is appreciated. :-)
In my opinion, it shouldn't be a big issue to raise the callback from your model, but I guess this depends on your architecture and your personal preferences.
So if you really don't want to have any callbacks connected to the view in your model, you could let your mvvm (or your presentation/application layer) handle the control flow instead of letting the model do it.
You could implement your model methods more fine grained and let the application layer coordinate the operations of your model. In that way, whenever a model operation is completed and a user input is required, the mvvm layer could raise the callback.
Example:
// method of your view model / application layer
public void InteractiveProcessing()
{
// business logic is separated in smaller chunks
model.DoFirstPartOfOperation();
// check if model needs additional user input
if(model.NeedsInput)
// raise callback here, let user enter input etc...
// continue processing with user input
model.DoSecondPartOfOperation(userInput);
}
Of course this makes only sense if you could split up your business logic into smaller parts.
You expose a public event, and have the View (.xaml.cs) to listen to it on startup. The code is still going to run on the worker thread, but the backend logic will not hang during unit testing.
OK, I think I've figured it out.
In my model I've encapsulated every call to the file system in a self-written interface called IIOServices and all my UI calls in an interface called IUIServices.
The UIServices only use standard datatypes or self-defined enums and nothing from the System.Windows.Forms or System.Windows namespace.
Then the clients of the model are responsible for providing an implementation to access FileOpenDialogs and MessageBoxes and such in any way they please.
My sample code for this implementation (which is kept small for the learning experience) can be found here, if anyone's interested:
MVVM with MessageBoxes sample code

Using classes to organize code?

At the moment my Form1 code is extremely heavy, mainly full of menu and control events. One thing I would like to do is organize it in some way, so I could expand or collapse "related code" (in Visual Studio).
My first attempt at this was to put code relating to the main menu, for example, inside a nested class called "MainMenu", which was within the Form1 class, so that I could simply collapse the nested class when I don't need it. This resulted in all sorts of problems (i.e. I couldn't find a way to set up the main menu inside this nested class).
Is there a simpler solution to this that I'm missing? Or can someone shed some light on why my nested class idea is faulty?
While #testalino's answer certainly does what you ask for, I would say that your real problem is probably related to code design. Chances are that the form class simply contains more code than it should, and that some of it ought to move into other classes.
If done in a good way, this might give you some benefits:
You will likely get more encapsulated (and less coupled) behavior, when various functions operates on data passed to the methods through parameters and return values instead of fetching and setting values directly in UI controls.
You might get a more testable code base (you do have unit tests, right?).
It will be easier for several persons to collaborate on the code, since the code is spread across several different code files. This reduces merging conflicts (you do have a source control system, right?). This point may not be as applicable if you are working on something alone, but it doesn't hurt to have this habit anyway.
You can use #region and #endregion to organize code within a class. These regions are then collapseable.
I suggest you using User Controls to encapsulate some of Form's behavior. This is the simplest solution available for you right now, I guess. You just pick some piece of user interface and extract it to user control and define some public properties accessible from the form.
Keeping all handlers in Form.cs is a bad, bad practice. You must avoid it because it's unmaintanable (I've seen much code like that, and at later stages adding or changing functionality is proven to be impossible without breaking anything, let alone changing the UI without affecting the way app works).
In future, you may want to try different approaches to separation UI from application logic, e.g. explore MVP/MVC patterns.
If your form has become so big and complex that you suddenly desire to organize it in some way it is a strong hint towards the need of refactoring, which will improve readability, testability and maintainablity of your code. How you actually refactor depends upon your actual code.
Is it a form that has a lot of controls? Think about splitting it up in separate UserControls where each of them displays a certain aspect of your domain data. Do you have a lot of interaction logic, reacting to a lot of events? Maybe introduce a some sort of Controller or EventAggregator.
There are a lot of well known patterns that can help you organize your UI and domain code. This series talks about just that and introduces you to patterns MVC, MVP, EventAggregator and much more. It discusses the patterns in the context of windows forms just as you need it.
Use the partial class keyword in order to split your class into several files.
I agree with what the other answers say about grouping alike event handlers together in #regions is solid given a massive number of events. In addition, if the code itself in the handlers is voluminous as well, you might want to think of refactoring those into logical business logic classes. Example:
pseudocode before:
private void SomeButton_Click(...)
{
using (FileStream fs = ...)
{
fs.Write(some form data);
fs.Write(some more form data);
}
DoMoreBusinessLogicStuff();
...
// lots more stuff
...
}
pseudocode after:
private void SomeButton_Click(...)
{
IBusinessObject obj = new BusinessObject(injectable form data);
using (IPersistence store = new FilePersistence(...))
{
obj.Persist(store);
}
obj.DoBusinessRules();
}
This should move business, persistence and support logic to their own classes and leave your event handlers as lightweight shells designed only to gather UI input and pass it along.
Nested classes are generally frowned upon as being only a slight upgrade from god-classes for one thing, and encapsulation and code reuse being pretty murky.
You should be aiming to express the objects you actually have as individual business classes within your code: one class, one file. Is there any particular reason you aren't doing this?
Depending on the type of code it is doing will depend on where you can move it.
If its processing data code then you can move this out into separate classes in a different namespace returning the processed data to controls to allow for data binding etc.
If Form1 is getting very heavy with code then is this because you've got too much going on in Form1? Could you break it out into a different/new form?
You could use the summary which is collapsible but I think this is more intended for providing other developers with information, always good practice though!
In VB:
''' <summary>
'''
''' </summary>
''' <remarks></remarks>
In C#
/// <summary>
///
/// </summary>
/// <remarks></remarks>

Should I use an event to notify a class or just use return?

I'm cutting my teeth on events and delegates today and to do so, I have been toying with the idea of experience bars, those progress bars from games. But I have a question about the better way to solve my problem - it could be as simple as bad design. Let me provide you some details.
I have modelled my idea with an ExperienceBar class.
It contains properties:
int StartValue
int CurrentValue
int EndValue
and a method
void UpdateBar(int)
UpdateBar adds the parameter to CurrentValue and then tests to see if it has reached EndValue. If it exceeds the amount, the EndValue increases and the amount continues on. Note that initially in my thinking, it is not concerned with the effects of reaching the maximum amount possible, just that the end value increases and the StartValue is reset to zero.
Another class called Player has a property of class ExperienceBar.
In my little demo, when Player.ExperienceBar.UpdateBar(int) reaches the EndValue it fires an event which is handled by the Player class. It updates the Player.Level property by one.
I've just realised that I could achieve the same thing by just changing UpdateBar(int) to return type "true". This method could be tested by the Player class and when true, Player.Level increases by one.
So my question - which is the best practice way to handle this rather specific circumstance? As a general rule of thumb for these kind of situations, is it better to handle events, or is it better just to keep it simple with the testing of return statements?
PS: I hope I've made this clear as possible, but I can try to clarify if anyone is having trouble. I believe there may be some redundancies already with my idea, but try not to deviate from the question please. I'm kind of aware of them! Thank you :)
Well... To me, events is the good way to do it.
However, if I was to design the application it would be down to one question: Will the ExperienceBars's event when it reaches EndValue ever be used by anyone else than the class calling UpdateBar.
If you are designing a component to be used in many places (which seems to be the goal), the answer to me seems to be an almost certain yes, therefore my answer is use events!
/Victor
In my opinion, there's no best way to do this. There are various ways to implement the class that, depending on how it is going to be used, are a better or worse fit.
Use events when you want to implement the observer pattern for many "clients" or "observers" who need to know the state of an object and need to be alerted when that state changes. this works for the degenerate case where there is only one client, but the caller of the the method that changes the object's state is not the one that needs to know about the change.
Use return values when the state only needs to be known by the caller, there are no other observers of the class. This is simple, and limits the scope of the knowledge of the state of the class to the item that immediately needs to know it.
And finally, do not over-design this. If it only needs to notify the caller, do not implement events. If at some later date the class needs to be "observed" then implement events at that point.
It all depends on the coupling of your components and the flow of your program. The downside to events is that you will increase the complexity of your program, because it is harder to trace exactly what the flow of execution will be when any piece of code can subscribe to your event. The upside is it allows for a more flexible and scalable design, since any piece of code can subscribe to your event.
So here is the thing, if Player is going to be in charge of handling all things related to leveling up, then having a tight coupling between Player and ExperienceBar is ok. Let's say you want to expose an AddIn framework, in that case you probably want to expose leveling up to external plugins, in which case an event makes a lot more sense.
Personally, I would have XP be a part of Player, and have Player expose a LevelUp event, but I don't know if that would be a good idea for you and your framework/domain modeling without seeing your existing code.
I would use events rather than a return value. Why? Two reasons:
What does returning true mean when returning from UpdateBar? That it was updated? That xyz happened? Someone else looking at this (or you, two months down the road) will wonder as well.
What if more than one thing should occur when the limit is reached? Then you have to tie all of the code related to those things (levelling, getting a new item, whatever) into the method that you used to update the bar in the first place.
I would have an event associated with reaching a certain level and then "listeners" for that event that can respond accordingly.
I don't think it makes sense to have Experience bar fire an event - in that case a return value would be fine. It could then call the Player's LevelUp function, which could fire an OnLevelUp event from the Player class, if needed.

a design problem with relatively complicated validations

i have a design problem.. it may seem that i'm giving you too much details, but those are important.
say i have a very large input form, with a complicated input, that requires quiet complicated validations, includes validations of relations between different inputs. being probably a very burdensome form for the user, i'd like to give him the ultimate experience, and i really don't want to be restricted by programing difficulties here.
i thought that idealic every control should have an empty value at start except those of course, that have default values (the problem is DateTimePicker and such are not supporting empty value).
now the user can fill in any of the controls, in any order he would like. once he has leave the control, the program will validate the control's value, and any of the others validations which are concern with that control, and with other controls that are all non-empty (have been filed in already).
if there are any validation errors, the control is painted in some color, and in some side panel it will specify the errors (in a user friendly language of course, rather than exceptions' descriptions).
if there are errors that concerns to more than one control, only the last one that has been changed is painted.
i'd really like to keep to as many OOP concepts here..
so i have my logic classes, that are dealing with calculating the output and stuff like that. obviously those have nothing to do with the gui. now all of these complicated validations should be also in the logic classes' properties etc. but should be used in the gui as well, so i think there should be something like static validate methods (within the logic classes), that will be used in the gui, and in the logic classes them self.
the problem is, a logic class might contain up to 20 maybe 30 fields to validate... will that static method take 30 parameters? is that okay or is there more acceptable solution?
i'm a bit lost for anything beyond that.. but i'm quite sure there already are some conventions for these situations... i know it has something to do with design patterns, but i have no idea what design patterns there are, which are dealing with such cases, and where should i read about them.
my question basically is how do i integrate the validation of the logic classes and the gui, in the neatest way.
if i already in that, i don't want to open a new question for these:
as i mentioned, i need a method here, that get all the input, all the fields of the class, and somehow perform all the validation checks on the non-null values (if there is a validation check that concern to a few parameters, and even one of them is null, the validation shall not be execute). if you have any interesting ideas, i'd like to hear.
another problem i bump into, is the non-emptyale controls, such as DateTimePicker.... it's really ugly that it will have a certain value, while it should not... don't you think?
p.s.
sorry about my english.. i was too tired to write it perfectly..
EDIT1 working with windows
will that static method take 30
parameters?
Yes but what if you pass your object into your static validation method instead of all its properties individually ex.
public static class YourClassRules
{
public List<SomeSortOfValidationItem> Validate(YourClass obj)
{
var results = new List<SomeSortOfValidationItem>()
if (obj.YourProperty.Length >= 200)
{
results.Add(new SormSortOfValidationItem("YourProperty", "Length must be less than...");
}
//etc.
}
}
my question basically is how do i
integrate the validation of the logic
classes and the gui, in the neatest
way.
There are several different frameworks available. It would be helpful to know if your doing windows or web. Then we could make some recomendations.
another problem i bump into, is the
non-emptyale controls, such as
DateTimePicker.
Are you having issues with the controls or the properties that are bound to the controls. I often use DateTime? or Nullable which will allow for a null value.
Hope this helps.
DataAnnotations can be very easy to implement and very effective. Read this answer for an alternative that can extend further. Also, this question has some great gems regarding validation models too.
Spring has a very good DataBinding and validation API. Since there is a Spring.NET version, I'd recommend looking into it.

Categories

Resources