C# - Determining responsibility between GUI and logic class - c#

I have a form and a logic class. Based on user actions, the class generates a list of actions. These actions then need to be displayed as buttons on the form, so the user can select from them.
My initial solution was this:
public class Logic {
public List<string> GetActions() {
List<string> result = new List<string>();
// ...prepare list
return result;
}
}
public class FrmGUI : Form {
Logic logic = new Logic();
private void PopulateButtons() {
foreach(string action in logic.GetActions(){
//...create button
}
}
}
The GUI retrieves the list of strings from the Logic class and then uses that to populate a panel with buttons. Now supposedly this is bad OO practise because I'm exposing something about how Logic class behaves. There is an assumption here that the GetActions method will always exist and that the Logic class will always be able to return this list of strings.
Another solution is this:
public class Logic {
public void PopulateButtons(Panel panel, Action<object, EventArgs> eventHandler) {
// ...prepare list
// ...populate buttons
}
}
public class FrmGUI : Form {
Logic logic = new Logic();
private void PopulateButtons() {
logic.PopulateButtons(this.panel1, actionButtonClickHandler);
}
}
Now here the GUI class knows nothing about the logic class and only expects to get the buttons populated. On the other hand, the logic class is now involved in GUI stuff.
What is the correct way to handle such cases. Or is there a third implementation which is better.

I'd use the former patttern: The Logic-layer creates information, and UI-layer uses that information to create the UI.
That way, if you decide to re-skin the UI to use a drop-down list of items you only have to change the UI layer, not the logic.
It means that the UI layer has a minimal dependency on the types/data provided by the logic layer (as long as it doesn't know anything about how the logic is implemented, that is fine), but the logic layer has no idea whatsoever about what the UI implementation is - which is what you want (the lower level components in a system should not know anything about the higher level design, while the higher level components must necessarily have a basic understanding of the low-level components that they utilise).
It would be preferable that the application (or some other external entity) creates both the Logic and UI and links them together, rather than the UI itself creating the Logic - this will help the UI and logic to be much more loosely coupled.

I would recommend placing a layer of abstraction between your Logic and your FrmGUI.
For a simplistic example, let's say you have a login in you application. Define an interface for your logical screen. Note there is no mention here of what controls are used. The Logic classes never knows the UI class/form used.
interface ILoginScreen : IScreen
{
event EventHandler LoginInvoked;
event EventHandler CancelInvoked;
string User { get; set; }
string Password { get; set; }
}
In your LoginLogic class you have code like this:
void Start() // initial LoginLogic method
{
ILoginScreen loginScreen = uiFactory.CreateLoginScreen();
loginScreen.User = string.empty;
loginScreen.Password = string.empty;
loginScreen.LoginInvoked += new EventHandler(LoginScreen_LoginInvoked);
loginScreen.CancelInvoked += new EventHandler(LoginScreen_CancelInvoked);
loginScreen.Show();
}
void LoginScreen_LoginInvoked(s, e)
{
if (ValidateCredentials(loginScreen.User, loginScreen.Password))
{
// goto the next screen logic controller
}
}
In your form, you implement ILoginScreen and refresh the UI fields with data from teh USer and Password properties. Additionally, you raise the required Login and Cancel events based on the user feedback (button click, Escape keystroke, whatever).
While this is a simplistic example, I do a lot of Windows Mobile and Windows CE apps where it is very common to want to run the same application on vastly different form-factors OS variants and this approach lets you literally snap on new GUI form-factors. The heart of that usage is the UIFactory that is dynamically loaded to provide the appropriate UI implementation.

That Logic can report the actions it supports (1st pattern) looks fine to me (but the return type of GetActions really should be IEnumerable<string> instead of a list).
Not so good is that in your sample the form instantiates the Logic class directly. Typically, you'd create an interface or abstract base class for the different types of Logic classes that you might have, and have concrete implementations fill in the functionality. The form would then get the logic to use through some inversion-of-control mechanism.

correct????? Over the years lots of people have invested lots of time in trying standardise this approach and I'm afraid the answer may be deduced from the number of ui design patterns out there!
You may want to look at MVC, MVP, MVVM patterns, all of which are in vogue at the moment.
In general:
it is a good idea to try to split logic from presentation, so you're on the right lines. But remember that one of the consequences of this split is that it is better for your "logic" not to know anything about presentation (since you already have a class responsible for that).
So you might want to think about the concept of "buttons", and think (from your logic point of view), "don't I really mean commands?". They only really become buttons when you think of them in the context of a screen. But, say, a command to load the transactions on a particular bank account....you don't need a screen to conceptualise how this would work.
A good thing I find is to imagine that you're going to develop this app with both a forms front end and, say, a web front end which does exactly the same thing. Obviously these two apps would have a totally different presentation layer because of the fundamentally different technologies involved.
But because you don't want to write code twice you'll have a "logic" layer too, where you'll stuff as much common code as you can. For example, deciding whether a bank account is overdrawn - doesn't matter whether you're web or win, overdrawn is still overdrawn. And conversely, any place where you'd end up writing different code between web and win belongs into your "presentation" layer. For example, displaying an overdrawn balance in red.
Food for thought.

the first one is better, because your interface between GUI and logic is just a list of string.
After, it all depends on the way you're calling actions on your logic class from your button.
If you have a generic method taking the action string, it's fine. If you need to call different methods on your logic class depending on the action string, you'll need a mapping in the GUI class to map action string and method call. you could also import this "action string - mapping method" from your logic class to keep things separated.

My opinion is, it depends on the reason for creating something like a logic tier and a GUI tier. I think the most common reason is to reuse the logic, e.g. to use it for a WPF and a web GUI, or the data has to be processed before sending it to the GUI. Your first example fits the mentioned pattern. In your second example the logic seems not to be reuseable, because its gui specific.
However, in the real world there it right or wrong answer. The architecture should fit your needs and make your project maintainable(e.g. by reduce redundant code).
In your case the question is: How often do you need these functions and where/when do you need them?

Related

How does one call a method on a 3rd party control without breaking MVVM convention?

My specific issue is an attempt to execute the Telerik DataBoundListBox method StopPullToRefreshLoading(true) from my ViewModel. The difficulty is that I do not want to break MVVM convention by putting application logic in the code behind.
I'm relatively new to MVVM and I'm not sure what the proper convention is for interacting with methods on controls on the view. I've done numerous searches on the topic and I've yet to find a solution that I can apply to my situation. I suspect I've probably come across the answer but I'm not drawing the proper conclusions.
It seems like this would be a common situation with 3rd party controls but maybe I'm just not thinking about the problem in the proper way.
I'm building my first Windows 8 Phone app using MVVM Light.
A lot of people get very hung up thinking that when following MVVM you MUST NOT HAVE CODE IN THE CODE BEHIND!!! This simply isn't the case, a design pattern like MVVM is there to make the code more maintainable. If something relates directly to the UI only and doesn't care about information in the viewmodel class then by all means put it in the code behind. I had the same situation when I was using third partly controls, sometimes there is no other option that isn't as bad or worse than putting code in the code behind.
First I agree with Chris McCabe on this, design patterns are a guideline, a framework, a suggestion. They are not rules to live-or-die by. That being said, you should be able to join the two (VM/Telerik) without introducing 'real' business logic into the UI.
The first possibility is to use an event on the controller. The UI can subscribe to this event to forward the call to the Telerik control; however, the UI should not decide when it is called.
class MyModel {
public event EventHandler StopRefreshLoading;
}
class myForm : Form {
public myForm(MyModel data)
{
data.StopRefereshLoading += (o, e) => this.CustomControl.StopPullToRefreshLoading(true);
// ... etc
}
Frankly, I prefer using interfaces for this type of behavior. It's then easy for the controller to force implementations to update to a new contract requirement. The downside is that the interfaces can become too verbose in a complex UI making them difficult to write tests for.
interface IMyModelView {
void StopRefreshLoading();
}
class myForm : Form, IMyModelView {
void IMyModelView.StopRefreshLoading()
{
this.CustomControl.StopPullToRefreshLoading(true);
}
Either direction you go some violation of the UI design pattern is likely to occur; however, in the real world there are no points for strictly adhering to a specific pattern. The patterns are there as an aid to make the code more reliable, testable, flexible, whatever. Decide why you are using a pattern and you will be able to evaluate when can safely violate that pattern.

I want a design alternative to a singleton

I realize there is much discussion about singletons and why that are bad. That is not what this question is about. I understand the drawbacks to singletons.
I have a scenario where using a singleton is easy and appears to make sense. However, I want an alternative that will accomplish what I need without a lot of overhead.
Our application is designed as a client that typically runs on laptops in the field and communicates with a back end server. We have a status bar at the bottom of the main application. It contains a few text areas that show various statues and information as well as several icons. The icons change their image to indicate their state. Such as a GPS icon that indicates if it is connected or not as well as error state.
Our main class is called MobileMain. It owns the status bar area and is responsible for creating it. We then have a StatusBarManager class. The StatusBarManager is currently a static class, but could also be a singleton. Here is the start of the class.
public static class StatusBarManager
{
static ScreenStatusBar StatusBar;
/// <summary>
/// Creates the status bar that it manages and returns it.
/// </summary>
public static ScreenStatusBar CreateStatusBar()
{
StatusBar = new ScreenStatusBar();
return StatusBar;
}
The MobileMain asks the StatusBarManager for a StatusBar. It then uses the StatusBar. No other classes see the StatusBar, just the StatusBarManager.
Updates to the status bar can come from pretty much anywhere in the application. There are around 20 classes that can update the text areas on the status bar and additional classes that update the icon states.
There will only every be one StatusBar and one StatusBarManager.
Any suggestions for a better implemention?
Some thoughts that I had:
Make the StatusBarManager an instance class. In my MobileMain class hold onto a static public instance of the StatusBarManager class. Then to do status bar updates you would call MobileMain.StatusBarManager.SetInformationText or some other method of the manager. The StatusBarManager would not be a singleton, but the MobileMain would only be creating a static instance of it. The issue here is that MobileMain now has a StatusBar and a StatusBarManager, which just manages the StatusBar it owns. Still also have a globally avaialble static instance to the StatusBarManager, just a different owner.
Another idea was to use something like an EventEggregator class. I've never used one, but have read about them. I guess the concept is that it would be a globally available class. In each class that wants to update the status bar it would publish a StatusBarUpdate event. The StatusBarManager would be the only classes subscribing to the StatusBarUpdate event, and receive all of the notifications. I've read though that can end up with leaks with this approach if you are not carefull with unsubscribing from events when cleaning up objects. Is this approach worth looking into?
I prefere Static classes that hold your objects. So the amount of objects you can access is restircted by the interface your static class offers. Static is not bad as long as your application still scales.
Another good alternative to singletons is the Monostate pattern, where you have a class that implements private static fields to represent "singleton" behavior.
See:
Monostate
Monostate vs. Singleton
UPDATE:
It often helps me to keep a REST like api in mind, even for internal program structures. Having one class that is updated from everywhere and sends notices to everybody is hard to control in respect to raise conditions and infinity loops (Update -> Event -> Update -> ...)
Build an (static or not) Status bar interface that you can access where you need it. Through a Static class where you get access to your Status bar interface or by dependency injection if you use such techniques (not recommended for smaller projects). Every call to your status bar interface has to be independent from any events that might be raised by the Status bar to avoid further issues with raise conditions. Think of the status bar interface like a website that can be called from other parts of the program to push and pull information.
Having a StatusBar class or a StatusBarManager class or not is not a big deal. But having many classes in your app know about StatusBars and StatusBarManagers is a bad idea, it will cause strong coupling, and some day probably pain.
How?
Imagine that the components that currently report status to a status bar have to be reused in another app that
- uses a text console to report status?
- reports status to multiple places?
or
- doesn't report status at all!
Best alternative:
-Event listening. Expose a Status Changed event on your class (you can use a callback), or perhaps on an existing shared resource that your classes have in common. Other parties, like your status bar, can subscribe to the event. And should unsubscribe whenever the subscription is no longer needed/valid, to prevent leaks, as you mention!
-Since you've tagged WPF, for WPF, having a dependency property 'StatusText', might seem like another tempting option, with this approach when you have multiple status properties, you need a way of figuring out which one is telling you the most interesting status that needs to be displayed on your status bar now! Which could be a binding, multibinding (blech, complexity), or dependency property changed event handler.
However - I would advise you to keep DependencyObjects and DependencyProperties limited to your UI layer as much as possible. The reason is that they rely implicitly on a Dispatcher on the UI thread, and so can't be adapted easily for non-UI chores.
Since there are many different parts of your app you may also possibly find it's reasonable to have a combination of both of these, using some one place and some another.
You could simply use the Observer pattern and add the StatusBar as a listener to your 20 objects. This will eliminate the singletons and better follow SRP and DIP, but you will have to consider whether it is worth the effort. A singleton may be better if the indirection adds too much complexity and dependency injection is not possible.
public class StatusBar implements StatusListener {
}
public interface StatusListener {
public statusChanged(String newStatus)
}
Classes will depend implicitly on any use singleton and explicitly to any parameters in the constructor. I would suggest adding an interface to the singleton, so just the methods needed would be exposed to the classes using the IStatusBar. This is more code, but will ease unit testing.
It's hard to give advice without knowing more of your application's architecture, but perhaps you should consider dependency injection. For example, pass a StatusBar instance to the constructor of each class that directly uses it.

Refactoring a large, complex user-interface

I have a big winform with 6 tabs on it, filled with controls. The first tab is the main tab, the other 5 tabs are part of the main tab. In database terms, the other 5 tabs have a reference to the main tab.
As you can imagine, my form is becoming very large and hard to maintain. So my question is, how do you deal with large UI's? How do you handle that?
Consider your aim before you start. You want to aim for SOLID principles, in my opinion. This means, amongst other things, that a class/method should have a single responsibility. In your case, your form code is probably coordinating UI stuff and business rules/domain methods.
Breaking down into usercontrols is a good way to start. Perhaps in your case each tab would have only one usercontrol, for example. You can then keep the actual form code very simple, loading and populating usercontrols. You should have a Command Processor implementation that these usercontrols can publish/subscribe to, to enable inter-view conversations.
Also, research UI design patterns. M-V-C is very popular and well-established, though difficult to implement in stateful desktop-based apps. This has given rise to M-V-P/passive view and M-V-VM patterns. Personally I go for MVVM but you can end up building a lot of "framework code" when implementing in WinForms if you're not careful - keep it simple.
Also, start thinking in terms of "Tasks" or "Actions" therefore building a task-based UI rather than having what amounts to a create/read/update/delete (CRUD) UI. Consider the object bound to the first tab to be an aggregate root, and have buttons/toolbars/linklabels that users can click on to perform certain tasks. When they do so, they may be navigated to a totally different page that aggregates only the specific fields required to do that job, therefore removing the complexity.
Command Processor
The Command Processor pattern is basically a synchronous publisher/consumer pattern for user-initiated events. A basic (and fairly naive) example is included below.
Essentially what you're trying to achieve with this pattern is to move the actual handling of events from the form itself. The form might still deal with UI issues such as hiding/[dis/en]abling controls, animation, etc, but a clean separation of concerns for the real business logic is what you're aiming for. If you have a rich domain model, the "command handlers" will essentially coordinate calls to methods on the domain model. The command processor itself gives you a useful place to wrap handler methods in transactions or provide AOP-style stuff like auditing and logging, too.
public class UserForm : Form
{
private ICommandProcessor _commandProcessor;
public UserForm()
{
// Poor-man's IoC, try to avoid this by using an IoC container
_commandProcessor = new CommandProcessor();
}
private void saveUserButton_Click(object sender, EventArgs e)
{
_commandProcessor.Process(new SaveUserCommand(GetUserFromFormFields()));
}
}
public class CommandProcessor : ICommandProcessor
{
public void Process(object command)
{
ICommandHandler[] handlers = FindHandlers(command);
foreach (ICommandHandler handler in handlers)
{
handler.Handle(command);
}
}
}
The key to handle a large UI is a clean separation of concerns and encapsulation. In my experience, it's best to keep the UI free of data and functionality as much as possible: The Model-View-Controller is a famous (but rather hard to apply) pattern to achieve this.
As the UI tends to get cluttered by the UI code alone it's best to separate all other code from the UI and delegate all things that don't concern the UI directly to other classes (e.g. delegating the handling of user input to controller classes). You could apply this by having a controller class for each tab, but this depends on how complicated each tab is. Maybe it's better to break a single tab down into several controller classes themself and compose them in a single controller class for the tab for easier handling.
I found a variation of the MVC pattern to be useful: The passive view. In this pattern, the view holds nothing more than the hierarchy and state of the UI components. Everything else is delegated to and controlled by controller classes which figure out what to do on user input.
Of course, it also helps to break the UI itself down into well organized and encapusalted components itself.
I would suggest you to read about the CAB ( Composite UI Application Block ) from Microsoft practice and patterns, which features the following patterns : Command Pattern, Strategy Pattern, MVP Pattern ... etc.
Microsoft Practice and patterns
Composite UI Application Block

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>

Using delegates instead of interfaces for decoupling. Good idea?

When writing GUI apps I use a top level class that "controls" or "coordinates" the application. The top level class would be responsible for coordinating things like initialising network connections, handling application wide UI actions, loading configuration files etc.
At certain stages in the GUI app control is handed off to a different class, for example the main control swaps from the login screen to the data entry screen once the user authenticates. The different classes need to use functionality of objects owned by the top level control. In the past I would simply pass the objects to the subordinate controls or create an interface. Lately I have changed to passing method delegates instead of whole objects with the two main reasons being:
It's a lot easier to mock a method than a class when unit testing,
It makes the code more readable by documenting in the class constructor exactly which methods subordinate classes are using.
Some simplified example code is below:
delegate bool LoginDelegate(string username, string password);
delegate void UpdateDataDelegate(BizData data);
delegate void PrintDataDelegate(BizData data);
class MainScreen {
private MyNetwork m_network;
private MyPrinter m_printer;
private LoginScreen m_loginScreen;
private DataEntryScreen m_dataEntryScreen;
public MainScreen() {
m_network = new Network();
m_printer = new Printer();
m_loginScreen = new LoginScreen(m_network.Login);
m_dataEntryScreen = new DataEntryScreen(m_network.Update, m_printer.Print);
}
}
class LoginScreen {
LoginDelegate Login_External;
public LoginScreen(LoginDelegate login) {
Login_External = login
}
}
class DataEntryScreen {
UpdateDataDelegate UpdateData_External;
PrintDataDelegate PrintData_External;
public DataEntryScreen(UpdateDataDelegate updateData, PrintDataDelegate printData) {
UpdateData_External = updateData;
PrintData_External = printData;
}
}
My question is that while I prefer this approach and it makes good sense to me how is the next developer that comes along going to find it? In sample and open source C# code interfaces are the preferred approach for decoupling whereas this approach of using delegates leans more towards functional programming. Am I likely to get the subsequent developers swearing under their breath for what is to them a counter-intuitive approach?
It's an interesting approach. You may want to pay attention to two things:
Like Philip mentioned, when you have a lot of methods to define, you will end up with a big constructor. This will cause deep coupling between classes. One more or one less delegate will require everyone to modify the signature. You should consider making them public properties and using some DI framework.
Breaking down the implementation to the method level can be too granular sometimes. With class/interface, you can group methods by the domain/functionality. If you replace them with delegates, they can be mixed up and become difficult to read/maintain.
It seems the number of delegates is an important factor here.
While I can certainly see the positive side of using delegates rather than an interface, I have to disagree with both of your bullet points:
"It's a lot easier to mock a method than a class when unit testing". Most mock frameworks for c# are built around the idea of mocking a type. While many can mock methods, the samples and documentation (and focus) are normally around types. Mocking an interface with one method is just as easy or easier to mock than a method.
"It makes the code more readable by documenting in the class constructor exactly which methods subordinate classes are using." Also has it's cons - once a class needs multiple methods, the constructors get large; and once a subordinate class needs a new property or method, rather than just modifying the interface you must also add it to allthe class constructors up the chain.
I'm not saying this is a bad approach by any means - passing functions rather than types does clearly state what you are doing and can reduce your object model complexity. However, in c# your next developer will probably see this as odd or confusing (depending on skill level). Mixing bits of OO and Functional approaches will probably get a raised eyebrow at the very least from most developers you will work with.

Categories

Resources