Avoiding large controllers in MVC - model-view-controller

Controllers can become large and unwieldy when they contain large numbers of actions. Is this a significant problem in real-world use, and if so what are the strategies to mitigate it (or is is good enough to simply keep the action-count down per controller)?
Off the top of my head I can envisage the controller offloading the logic to action implementations in other types, grouped according to some meaningful heuristic.

In my experience, this mostly happens when I don't apply the "REST" knife aggressively enough. Sometimes the metaphor is not consistent with the way we think about a problem; for example, it's easy to think that "login" is an action on "account", but if you apply the REST knife, you realize that logging in is really "starting a new session" and you invert the idea by applying a "new" (or Create) action on a SessionController. Then you have a small controller responsible for creating and destroying sessions (logging in and logging out).
I'm sure a few people will not be fond of muddying the REST waters with the messy concept of authentication, so let's look at a more obvious example. I can have a BlogPost entity, and it can have a bunch of comments. Rather than having an action AddComment on the BlogPostController, I have the usual create/edit/delete methods on BlogPost, and another controller CommentController whose new/create actions expect a BlogPostId, and implements create/edit/delete methods.
I've run into some situations where I needed a non-REST-like action, such as "import a list of X from a CSV file", each of whom belongs to a Y; the "list" isn't really important as a domain concept, as I'm really just trying to add to an existing collection of Xes. In that case, I took what I perceive to be a slightly ugly approach of adding an "import" action to my XController. That code is the messiest code in any of my controllers, and I'd be inclined to factor it out into something with more contained responsibility (an XImporter class, perhaps), but for now it "works." I'm sure someone more clever than me would have a better solution.
So my argument is this: If you have lots of un-RESTy actions, there's a kind of code smell; perhaps you aren't modeling what you're controlling correctly. But if you have say, 1-3 unRESTy actions and attempts to rethink the problem don't lead you in the right direction, perhaps it's not worth worrying about.

Related

MVC: why the separation of model, view, and controller?

Other than the “philosophical” aspects of it, is it a bad idea to have my controller also be my model?
It seems to save some programming time. I don’t have to create logic between the controller and the model, since it’s the same thing. And I can directly interact with the view.
What’s the point of separating the M and the C? Is modularity — that is, the ability to swap one model and controller set for another — the only reason to separate them? It seems to me that “swapping” modules out happens a lot less than (for example) having to update both the model and the controller because something in the model is changing.
It seems odd that a simple calculator, according to the MVC concept, should have both a controller and a view for its settings (like default settings, or something). I know this is a simple example, but it seems to apply to all cases (except maybe frameworks).
The primary reason is for reusability of code. If you’re only ever going to write one program in your professional life, then perhaps it doesn’t matter. If you plan to make a career of it, having reusable pieces is valuable. Well-designed model, controller and view classes are very easy to drop into other programs. I do this all the time.
Consider UITableViewController, which is a Controller. Now imagine if it were designed exclusively to handle music tracks (the Model), and you needed to create a completely different table-management class when you wanted to handle something else. Avoiding this nightmare is why MVC is heavily used in Cocoa.
There are other ways to split things up. Some languages subclass heavily rather than delegating. But in Cocoa, the primary means of splitting up programs is MVC, and it works very well.
EDIT: Just some more reasons from the world of developing commercial apps.
Memory handling is much easier in MVC. You can hold on to your model objects and throw away your view objects (and many of your controller objects) when they go offscreen.
It’s easier to serialize model objects that aren’t wrapped up with controllers and views, and it’s much easier to display the same data in multiple ways. Even in a “simple” text editor, you may want to be able to do split-screen, or have multiple windows showing the same document. In MVC that’s very easy.
If you need no flexibility now or in the future, you don’t need much architecture. But most real projects aren’t so simple. MVC grew out of Xerox’s experience with writing large programs and the difficulties encountered when everything was thrown together.
EDIT 2: I was looking at your earlier edit: “It seems odd that a simple calculator, according to the MVC concept, should have both a controller and a view for its settings (like default settings, or something).”
This is exactly the reason for MVC. It would seem crazy to have to re-code all of the things required for saving user settings specially for a Calculator app. You’d want a generic “please save these user settings” that was completely separate from the UI and that you could reuse. On OS X it’s called NSUserDefaults, and the Calculator app stores its configuration in exactly this way.
MVC is a standard pattern that is well understood in the development community, and for good reasons. The separation really makes things easy to read, easy to troubleshoot, easy to find, and easy to test, as individual components, each with its own area of responsibility.
Do you have to use it? of course not. But keeping the parts separate is generally considered a good idea.
The controller knows how to link a specific view to your model. The separation of model and controller, apart from improving documentation and maintainability, has the immediate benefit of allowing multiple views to display the same information from the model without adding any complexity to either.
That applies not just to multiple views in the same application, but also to the multiple variations in views you'll have across multiple versions of your application. Your model is insulated and logically clean.
Combining model and controller is a classic false economy in my opinion. It may feel like it saves a few minutes, but it costs significantly as an application develops and grows.
If it works for you then it works. Period. The reason for separation of Models, Views, and Controllers revolves around the idea that most development for enterprise applications is done by a team of developers.
Imagine 10 developers trying to work on your controller. But all they want to do is add something to the model. Now your Controller broke? What did they do?
The Models are usually separate components which can be re-used between Controllers. If you are absolutely certain you won't be re-using Models in multiple Controller, I don't really see a problem with blending these concerns.
I guess one could argue why even use MVC design if you are planning on deviating. Maybe there is a more suitable pattern to follow for your situation. Can you give us an example of something you've done where the Controller is the Model? It would help us understand what you are trying to do better.
MVC is all about management (separation of data, representation and business logic). So it's like this: if you run a small company, having a MS-sized management would be a real drag. But if you are a giant corporation, not having big middle management is impossible.
Honestly, in most of my college progamming assignments, I combined the models and controllers, because I didn't see the need for the separation. But working on big projects? The deficiency would be pretty obvious if you try to not separate. Just do what you feel right.
The model depends on neither the view nor the controller. This is one the key benefits of the separation. This separation allows the model to be built and tested independent of the visual presentation.

Stories and Scenarios that implies UI

I am trying to learn how to use BDD for our development process and I sometimes end-up writing things that implies a UI design, so for brand new development or new features, the UI does not always exists.
For example, if I say this in a scenario "When a column header is clicked" it implies that this feature is based on some sort of table or grid, but at this point we are still just writing user-stories so there is no UI yet.
That gets me confused to know at what point in the process do we come up with a UI design ?
Keep in mind, I only have read articles about BDD and I think it would help our team a lot but still very new at this! Thx!
If you write your scenarios with a focus on the capabilities of the system, you'll be able to refactor the underlying steps within those scenarios more easily. It keeps them flexible. So I'd ask - what does clicking the column get for you? Are you selecting something? What are you going to do with the selection? Are you searching for something and sorting by a value?
I like to see scenarios which say things like:
When I look for the entry
When I go to the diary for January
When I look at the newest entries
When I look at the same T-shirt in black
These could all involve clicking on a column header, but the implementation detail doesn't matter. It's the capability of the system.
Beneath these high-level scenarios and steps I like to create a screen or page with the smaller steps like clicking buttons in it. This makes it easy to refactor.
I wrote this in a DSL rather than English, but it works with the same idea - you can't tell from the steps whether it's a GUI or a web page, and some of the steps involve multiple UI actions:
http://code.google.com/p/wipflash/source/browse/Example.PetShop.Scenarios/PetRegistrationAndPurchase.cs
Hope you find it interesting and maybe it helps. Good luck!
I guess you can write around that by saying "when I sort the information by X, then..." But then you would have to adjust your scenario to remove any mention of the data being displayed in a grid format, which could lead to some rather obtuse writing.
I think it's a good idea to start with UI design as soon as you possibly can. In the case you mentioned above, I think it would be perfectly valid to augment the user story with sketch of the relevant UI as you would imagine it, and then refine it as you go along. A pencil sketch on a piece of paper should be fine. Or you could use a tablet and SketchBook Pro if you want something all digital.
My point is that I don't see a real reason for the UI design to be left out of user stories. You probably already know that you're going to build a Windows, WPF, or Web application. And it's safe to assume that when you want to display tabular data, you'll be using a grid. Keeping these assumptions out of the requirements obfuscates them without adding any real value.
User stories benefit from the fact, that you describe concrete interactions and once you know concrete data and behaviour of the system for it, you might as well add more information about the way you interact. This allows you to use some tools like Cucumber, which with Selenium enables you to translate a story to a test. You might go even further and e.g. for web apps capture all pages you start concrete story at and collect all interactions with that page resulting in some sort of information architecture you might use for documentation or prototyping and later UI testing.
On the other hand, this makes your stories somewhat brittle when it comes to UI changes. I think the agile way of thinking about this is same as when it comes to design changes - do not design for the future, do the simplest possible thing, in the future you might need to change it anyway.
If you stripped your user stories of all concrete things (even inputs) you will end up with use cases(at least in their simplest format, depends on how you write your stories). Use cases are in this respect not brittle at all, they specify only goals. This makes them resistant to change, but its harder to transfer information automatically using tools.
As for the process, RUP/UP derives UI from use cases, but I think agile is in its nature incremental (I will not say iterative, this would exclude agile methods like FDD and Kanban). This means, as you implement new story, you add to your UI what is necessary. This only makes adding UI specifics in stories more reasonable. The problem is, that this is not a very good way to create UI or more generally UX(user experience). This is exactly what one might call a weakpoint of agile. The Agile manifesto concentrates on functional software, but that is it. There are as far as I know no agile techniques for designing UI or UX.
I think you just need to step back a bit.
BAD: When I click the column header, the rows get sorted by the column I clicked.
GOOD: Then I sort the rows by name, or sometimes by ZIP code if the name is very common, like "Smith".
A user story / workflow is a sequence of what the user wants to achieve, not a sequence of actions how he achieves that. You are collecting the What's so you can determine the best How's for all users and use cases.
Looking at a singular aspect of your post:
if I say this in a scenario "When a column header is clicked" it implies that this feature is based on some sort of table or grid, but at this point we are still just writing user-stories so there is no UI yet.
If this came from a user, not from you, it would show a hidden expectation that there actually is a table or grid with column headers. Even coming from you it's not entirely without value, as you might be a user, too. It might be short-sighted, thinking of a grid just because it comes from an SQL query, or it might be spot-on because it's the presentation you expect the data in. A creative UI isnÄt a bad thing as such, but ignoring user expectations is.

What do you call a generalized (non-GUI-related) "Model-View-Controller" architecture?

I am currently refactoring code that coordinates multiple hardware components for data acquisition, and feeling a bit like I'm recreating the wheel. In particular, an MVC-like pattern seems to be emerging. Except, this has nothing to do with a GUI and I'm worried that I'm forcing this particular pattern where another might be more appropriate. Here's my scenario:
Individual hardware "component" classes obey interface contracts for each hardware type. Previously, component instances were orchestrated by a single monolithic InstrumentController class, which relied heavily on configuration + branching logic for executing a specific acquisition sequence. After an iteration, I have a separate controller for each component, with these controllers all managed by a small InstrumentControllerBase (or its derivatives). The composite system will receive "input" either programmatically or via inter-hardware component triggering - in either case these interactions are routed to, and handled by, the appropriate controller.
So, I have something that feels MVC-esque, but I don't know if that's because I'm forcing the point. With little direct MVC experience in application development, it's hard to know if I'm just trying to make my scenario fit MVC, where another pattern might be a good alternative or complimentary. My problem is, search results and wiki documentation of these family of patterns seems to immediately drop me into GUI-specific discussions.
I understand "M means Model data and the V means View" - but what do you call the superset pattern? Component-Commander-Controller?
Whence can I exhume examples exemplary?
IMO a "view" is not necessarily a GUI component. The pattern is easiest to demonstrate with GUIs but that does not limit its usability to GUIs. If it works for you, don't worry about the name :-) And of course, feel free to tailor it according to your needs.
Update: Of more generic kins of MVC, the only example which surfaced in my mind (after a day's background processing) is PAC.

Interface Insanity

I'm drinking the coolade and loving it - interfaces, IoC, DI, TDD, etc. etc. Working out pretty well. But I'm finding I have to fight a tendency to make everything an interface! I have a factory which is an interface. Its methods return objects which could be interfaces (might make testing easier). Those objects are DI'ed interfaces to the services they need. What I'm finding is that keeping the interfaces in sync with the implementations is adding to the work - adding a method to a class means adding it to the class + the interface, mocks, etc.
Am I factoring the interfaces out too early? Are there best practices to know when something should return an interface vs. an object?
Interfaces are useful when you want to mock an interaction between an object and one of its collaborators. However there is less value in an interface for an object which has internal state.
For example, say I have a service which talks to a repository in order to extract some domain object in order to manipulate it in some way.
There is definite design value in extracting an interface from the repository. My concrete implementation of the repository may well be strongly linked to NHibernate or ActiveRecord. By linking my service to the interface I get a clean separation from this implementation detail. It just so happens that I can also write super fast standalone unit tests for my service now that I can hand it a mock IRepository.
Considering the domain object which came back from the repository and which my service acts upon, there is less value. When I write test for my service, I will want to use a real domain object and check its state. E.g. after the call to service.AddSomething() I want to check that something was added to the domain object. I can test this by simple inspection of the state of the domain object. When I test my domain object in isolation, I don't need interfaces as I am only going to perform operations on the object and quiz it on its internal state. e.g. is it valid for my sheep to eat grass if it is sleeping?
In the first case, we are interested in interaction based testing. Interfaces help because we want to intercept the calls passing between the object under test and its collaborators with mocks. In the second case we are interested in state based testing. Interfaces don't help here. Try to be conscious of whether you are testing state or interactions and let that influence your interface or no interface decision.
Remember that (providing you have a copy of Resharper installed) it is extremely cheap to extract an interface later. It is also cheap to delete the interface and revert to a simpler class hierarchy if you decide that you didn't need that interface after all. My advice would be to start without interfaces and extract them on demand when you find that you want to mock the interaction.
When you bring IoC into the picture, then I would tend to extract more interfaces - but try to keep a lid on how many classes you shove into your IoC container. In general, you want to keep these restricted to largely stateless service objects.
Sounds like you're suffering a little from BDUF.
Take it easy with the coolade and let it flow naturally.
Remember that while flexibility is a worthy objective, added flexibility with IoC and DI (which to some extent are requirements for TDD) also increases complexity. The only point of flexibility is to make changes downstream quicker, cheaper or better. Each IoC/DI point increases complexity, and thus contributes to making changes elsewhere more difficult.
This is actually where you need a Big Design Up Front to some extent: identify what areas are most likely to change (and/or need extensive unit testing), and plan for flexibility there. Refactor to eliminate flexibility where changes are unlikely.
Now, I'm not saying that you can guess where flexibility will be needed with any kind of accuracy. You'll be wrong. But it's likely that you'll get something right. Where you later find you don't need flexibility, it can be factored out in maintenance. Where you need it, it can be factored in when adding features.
Now, areas which may or may not change depends on your business problem and IT environment. Here are some recurring areas.
I'd always consider external
interfaces where you integrate to
other systems to be highly mutable.
Whatever code provides a back end to
the user interface will need to support change in the UI. However, plan for changes in functionality primarily: don't go overboard and plan for different UI technologies (such as supporting both a smart client and a web application – usage patterns will differ too much).
On the other hand, coding for
portability to different databases
and platforms is usually a waste
of time at least in corporate
environments. Ask around and check
what plans may exist to replace or
upgrade technologies within the
likely lifespan of your software.
Changes to data content and formats are a tricky
business: while data will
occasionally change, most designs
I've seen handle such changes
poorly, and thus you get concrete
entity classes used directly.
But only you can make the judgement of what might or should not change.
I usually find that I want interfaces for "services" - whereas types which are primarily about "data" can be concrete classes. For instance, I'd have an Authenticator interface, but a Contact class. Of course, it's not always that clear-cut, but it's an initial rule of thumb.
I do feel your pain though - it's a little bit like going back to the dark days of .h and .c files...
I think the most important "agile" principle is YAGNI ("You Ain't Gonna Need It"). In other words, don't write extra code until it's actually needed, because if you write it in advance the requirements and constraints may well have changed when(if!) you finally do need it.
Interfaces, dependency injections, etc. - all this stuff adds complexity to your code, making it harder to understand and change. My rule of thumb is to keep things as simple as possible (but no simpler) and to not add complexity unless it gains me more than enough to offset the burden it imposes.
So if you are actually testing and having a mock object would be very useful then by all means define an interface that both your mock and real classes implement. But don't create a bunch of interfaces on the purely hypothetical grounds that it might be useful at some point, or that it is "correct" OO design.
Interfaces have the purpose of establishing a contract and are particularly useful when you want to change the class performing a task on the fly. If there is no need to change the classes an interface just might get in the way.
There are automatic tools to extract the interface, so maybe you'd better delay the interface extraction later in the process.
It depends very much on what you are providing... if you are working on internal things then the advice of "don't do them until needed" is reasonable. If, however, you are making an API that is to be consumed by other developers then changing things around to interfaces at a later date can be annoying.
A good rule of thumb is to make interfaces out of anything that needs to be subclasses. This is not an "always make an interface in that case" sort of thing, you still need to think about it.
So, the short answer is (and this works with both internal things and providing an API) is that if you anticipate more than one implementation is going to be needed then make it an interface.
Somethings that generally would not be interfaces would be classes that only hold data, like say a Location class that deals with x and y. THe odds of there being another implementation of that is slim.
Do not create the interfaces first - you ain't gonna need them. You cannot guess for which classes you'll need an interface of for which classes you don't. Therefore do not spend any time to burden the code with useless interface now.
But extract them when you feel the urge to do so - when you see the need of an interface - at the refactoring step.
Those answers can help too.

Performance of using static methods vs instantiating the class containing the methods

I'm working on a project in C#. The previous programmer didn't know object oriented programming, so most of the code is in huge files (we're talking around 4-5000 lines) spread over tens and sometimes hundreds of methods, but only one class. Refactoring such a project is a huge undertaking, and so I've semi-learned to live with it for now.
Whenever a method is used in one of the code files, the class is instantiated and then the method is called on the object instance.
I'm wondering whether there are any noticeable performance penalties in doing it this way? Should I make all the methods static "for now" and, most importantly, will the application benefit from it in any way?
From here, a static call is 4 to 5 times faster than constructing an instance every time you call an instance method. However, we're still only talking about tens of nanoseconds per call, so you're unlikely to notice any benefit unless you have really tight loops calling a method millions of times, and you could get the same benefit by constructing a single instance outside that loop and reusing it.
Since you'd have to change every call site to use the newly static method, you're probably better spending your time on gradually refactoring.
I have dealt with a similar problem where i work. The programmer before me created 1 controller class where all the BLL functions were dumped.
We are redesigning the system now and have created many Controller classes depending on what they are supposed to control e.g.
UserController, GeographyController, ShoppingController...
Inside each controller class they have static methods which make calls to cache or the DAL using the singleton pattern.
This has given us 2 main advantages. It is slightly faster(around 2-3 times faster but were talking nanoseconds here ;P). The other is that the code is much cleaner
i.e
ShoppingController.ListPaymentMethods()
instead of
new ShoppingController().ListPaymentMethods()
I think it makes sense to use static methods or classes if the class doesn't maintain any state.
It depends on what else that object contains -- if the "object" is just a bunch of functions then it's probably not the end of the world. But if the object contains a bunch of other objects, then instantiating it is gonna call all their constructors (and destructors, when it's deleted) and you may get memory fragmentation and so on.
That said, it doesn't sound like performance is your biggest problem right now.
You have to determine the goals of the rewrite. If you want to have nice testable, extendable & maintainable OO code then you could try to use objects and their instance methods. After all this is Object Oriented programing we're talking about here, not Class Oriented programming.
It is very straightforward to fake and/or mock objects when you define classes that implement interfaces and you execute instance methods. This makes thorough unit testing quick and effective.
Also, if you are to follow good OO principles (see SOLID at http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29 ) and/or use design patterns you will certainly be doing a lot of instance based, interface based development, and not using many static methods.
As for this suggestion:
It seems silly to me to create an object JUST so you can call a method which
seemingly has no side effects on the object (from your description i assume this).
I see this a lot in dot net shops and to me this violates encapsulation, a key OO concept. I should not be able to tell whether a method has side effects by whether or not the method is static. As well as breaking encapsulation this means that you will need to be changing methods from static to instance if/when you modify them to have side effects. I suggest you read up on the Open/Closed principle for this one and see how the suggested approach, quoted above, works with that in mind.
Remember that old chestnut, 'premature optimization is the root of all evil'. I think in this case this means don't jump through hoops using inappropriate techniques (i.e. Class Oriented programming) until you know you have a performance issue. Even then debug the issue and look for the most appropriate.
Static methods are a lot faster and uses a lot less memory. There is this misconception that it's just a little faster. It's a little faster as long as you don't put it on loops. BTW, some loops look small but really aren't because the method call containing the loop is also another loop. You can tell the difference in code that performs rendering functions. A lot less memory is unfortunately true in many cases. An instance allows easy sharing of information with sister methods. A static method will ask for the information when he needs it.
But like in driving cars, speed brings responsibility. Static methods usually have more parameters than their instance counterpart. Because an instance would take care of caching shared variables, your instance methods will look prettier.
ShapeUtils.DrawCircle(stroke, pen, origin, radius);
ShapeUtils.DrawSquare(stroke, pen, x, y, width, length);
VS
ShapeUtils utils = new ShapeUtils(stroke,pen);
util.DrawCircle(origin,radius);
util.DrawSquare(x,y,width,length);
In this case, whenever the instance variables are used by all methods most of the time, instance methods are pretty worth it. Instances are NOT ABOUT STATE, it's about SHARING although COMMON STATE is a natural form of SHARING, they are NOT THE SAME. General rule of thumb is this: if the method is tightly coupled with other methods --- they love each other so much that they when one is called, the other needs to be called too and they probably share the same cup of water---, it should be made instance. To translate static methods into instance methods is not that hard. You only need to take the shared parameters and put them as instance variables. The other way around is harder.
Or you can make a proxy class that will bridge the static methods. While it may seem to be more inefficient in theory, practice tells a different story. This is because whenever you need to call a DrawSquare once (or in a loop), you go straight to the static method. But whenever you are gonna use it over and over along with DrawCircle, you are gonna use the instance proxy. An example is the System.IO classes FileInfo (instance) vs File (static).
Static Methods are testable. In fact, even more testable than instance once. Method GetSum(x,y) would be very testable to not just unit test but load test, integrated test and usage test. Instance methods are good for units tests but horrible for every other tests (which matters more than units tests BTW) that is why we get so many bugs these days. The thing that makes ALL Methods untestable are parameters that don't make sense like (Sender s, EventArgs e) or global state like DateTime.Now. In fact, static methods are so good at testability that you see less bugs in C code of a new Linux distro than your average OO programmer (he's full of s*** I know).
I think you've partially answered this question in the way you asked it: are there any noticeable performance penalties in the code that you have?
If the penalties aren't noticeable, you needn't necessarily do anything at all. (Though it goes without saying the codebase would benefit dramtically from a gradual refactor into a respectable OO model).
I guess what I'm saying is, a performance problem is only a problem when you notice that it's a problem.
It seems silly to me to create an object JUST so you can call a method which seemingly has no side effects on the object (from your description i assume this). It seems to me that a better compromise would be to have several global objects and just use those. That way you can put the variables that normally would be global into the appropriate classes so that they have slightly smaller scope.
From there you can slowly move the scope of these objects to be smaller and smaller until you have a decent OOP design.
Then again, the approach that I would probably use is different ;).
Personally, I would likely focus on structures and the functions which operate on them and try to convert these into classes with members little by little.
As for the performance aspect of the question, static methods should be slightly faster (but not much) since they don't involve constructing, passing and deconstructing an object.
It's not valid in PHP,
Object Method is faster :
http://www.vanylla.it/tests/static-method-vs-object.php

Resources