CleanSwift - Can a presenter directly call router function? - ios

I am working on CleanSwift architecture. I see there is no direct communication between a presenter and associated scenes router in diagram,
But often there are certain scenarios where a presenter only needs to rout to another view controller. I wonder if its permitted for presenter to call a router routeToOtherView() function directly, rather calling an extra function in view controller which simply redirect.

I have also used CleanSwift in couple of projects. What I liked about this architecture is that it works in unidirectional flow. And in this flow ViewController works with Router, Interactor and Presenter. Unidirectional flow allows us to find bugs easily.
Let's take one scenario to understand this. Suppose you have a Button and click on that you want to move from ViewController1 to ViewController2. By any mistake you write ViewController3 instead of ViewController2, now it's showing ViewController3 on Button click. To solve this bug you have to look at routing mechanism. And you know that routing mechanism resides in the ViewController1, so to solve it you should just move on to ViewController1 and find the responsible function for route and solve the bug.
You are breaking the flow, if you move routing in Presenter for some of the cases when there is only need is to move from one Controller to another. Also the architecture will be dependant on you because you have to keep in mind that whether you have added routing mechanism in Presenter or in Controller. It also affects the collaborative environment, where your counter part has to search for the routing mechanism. It will also take time to solve the bug if you observe the above Scenario.
So it's better idea to don't break the flow. It's good to spend more to make it precious. Hope this answer can help.

Related

Should a class ever hold data for the purpose of passing it on to another class?

I am creating a login app for iOS and have stumbled upon a design issue. In my app some data (e.g. current user id) has to be shared across view controllers so my initial thought was to hold that data in the AppDelegate and just call it from there whenever it was needed. This would work but it would mean that the AppDelegate would be doing work that it wasn't intended to do and hence it would be bad architecture, so I thought of creating a singleton class to hold all the shared data instead. This seems to be more focused and I have used this strategy in some of my previous apps, but googling the best practices for singleton classes, I found many results against using them, as they:
Hide dependencies
Violate the single responsibility principle
Make unit testing difficult
(taken from the top answer to this question: What is so bad about singletons?)
The alternative to the two other design patterns would then be to pass data back an forth between view controllers, but this again seems inappropriate. Take for example the current user id I would have to pass it from the login view controller to the main view controller (which is the same for all users), then from the main view controller to a more specified view controller which is customized for the user. In this case the main view controller is holding data only for the purpose of passing it to the more specific view controller and to me this also seems to violate the single responsibility principle. Would it be bad design to let the main view controller hold data it doesn't need or is there a better alternative?
There is no "magic" way of storing the model state of your model-view-controller application: you build a class, and you "anchor" it somewhere for easy access.
One common practice is using the app delegate. It is convenient, because it is a system-supplied singleton globally available to your app, but it is logically inferior, because, as you noted, app delegate was not intended for that.
Another common strategy is using a singleton. This is commonplace in app development, and it works fine in practice. You can mitigate the common grievances by limiting the access to your singleton to initializers of your view controller - this addresses the hidden dependencies and the testability issues.
Finally, you can pass the data around, in which case it is the same as "anchoring" it in one of the view controllers. Arguably, this leads to even bigger problems than singletons, because the dependencies become even harder to trace.
I would recommend storing the state in a singleton, and use it in the initialization code of your view controllers. This way the dependency on the singleton remains localized, and you could test your logic with minimal effort.

what is the best way to bind ViewModel data to master page in asp.net-mvc

I want to dynamically create my menu on my master page and i have seen 2 different approaches:
First approach is have a base controller that loads up all shared view model data in its constructor. This is described here
Second approach is to create a separate controller for this and use this in your master page to inject specific view pieces into the master page without polluting your regular page view generation:
#Html.Action("Index", "Settings")
Is one better than the other? Is there any best practice here?
Personally I prefer the second approach as it allows to handle the menu independently from the main logic. By using child actions you could have an entirely separate lifecycle of the menu controller without the need to have a base view model for absolutely all views that use this masterpage. Inheritance just doesn't seem right for this situation but of course this doesn't mean that you should rule it out completely. Every scenario is specific and depending on the exact details (which you haven't provided for yours) there might different approaches.
Just don't think that if Html.Action is good for one scenario it will be good for all of them. There might be some project specific constraints which make inappropriate or maybe achieve this by some other approach.
There is no universal solution that will work in all situations. Otherwise there wouldn't be a need for programmers :-)

Which is better - relying on delegates or persisting through objects - iOS

After doing some reading I notice Apple pushes the use of delegates on controllers communicating with one another.
So say I have a Menu controller which needs to communicate with the help controller (and they need to share info - lol don't ask me why they would). I could do this through delegates, but why use delegates when I can pass the required information on through a help object and have the help controller pick back up this info that was changed in the previous controller.
Delegates still couples - however loosely it may be, wouldn't the use of objects be the best practice here for re usability?
Delegates are great for responses, especially if the response isn't going to be immediate.
If you're simply telling the help controller something like what information to display, passing it directly is great. If you want to know, for example, when the help controller is done displaying help for the user a delegate is clearer and usually superior.

Keeping a controller thin (too many action methods)

I'm working on my first real ASP.NET MVC project and I've noticed that the controller I've been working in is getting rather large. This seemingly goes against the best practice of keeping your controllers thin.
I've done a good job keeping the business logic out of the controllers. I use a separate layer for that. Each action primarily calls a method in the business layer and coordinates the end result based on whether or not the modelstate is valid.
That said, the controller has a large number of action methods. Intuitively, I would like to break the controller down into sub-controllers but I don't see an easy way to do that. I could simply break the controller down into separate controllers but the I loose the hierarchy and it feels a bit dirty.
Is it necessary to refactor a controller with a large number of thin actions? If so, what is the best way to do this?
First, when you hear that it's good to keep controller code to a minimum, this mainly refers to keeping each action method as thin as possible (put logic instead into business classes, not into Views and ViewModels.) It seems you're doing this, which is great.
As for having "too many" action methods, this is a judgment call. It could actually be a sign of good organization, that you're having each action focus on one thing. Also, maybe you're using actions specifically for use with RenderAction? And, it could just be the nature of your solution that there are many things to do relating to your Controller's theme.
So, my guess is that you're probably fine. However, to make sure, on note paper break out the controller into 2 or 3 controllers, and sketch out how your stories would work moving from action to action. And if you find that your workflow works with more controllers, you should break it out. Especially if you're going to be adding to this functionality later. The sooner your break it out the better.
Good question.
I believe a "thin" controller may still need to be "wide" or "tall" depending on how you want to stretch the analogy. If there is no clean way to break up a controller that needs to do a lot of things, I don't think that's a problem as long as each Action is focused exclusively on preparing Views/ViewModels and is of limited code size.
Another structural option you have is introducing partial classes for logical groupings of actions. And using something like vscommands to group the files together.
I doubt anybody can come up with a magic number of actions that tells you when it's a good idea to break stuff up and introduce new controllers, it really depends on your domain.
Another solution can be to separate the controllers based on the business concepts of the actions that are included in them, but the route of each action is in accordance with the REST rules.
However, I think it is better to use this solution only in cases where there is a fat controller, otherwise, it is better to categorize actions based on their output resources.

Where to Authorize Access to a Controller

I have the following Filter on my Controller:
[Authorize(Roles="Admin")]
public class AdminOnlyController : Controller
{
// stuff
}
I showed a couple of guys here at work what I'm doing, and a huge debate emerged with some of the guys claiming that Authorization should not be a responsibility of the Controller. This is the way I learned to do it, according to the book Pro ASP.NET MVC Framework by Steven Sanderson.
None of the other guys were able to suggest how it should be done, other than that it was wrong.
Is it? Is there a better way?
The simple answer is yes - that is the best way. The Controllers' Actions are the end point for ALL requests to the application. It makes perfect sense to put the authorisation there.
You could farm the authorisation out to IIS, but that worked better when access was controlled to files (.aspx etc). Now we have a MVC with which you have to control access to multiple actions within one controller.
There's two ways to assign authorization. The controller class or the ActionResult. As opposed to how else you could do it, I'm not very sure.
I don't really see the side of the argument where you argue against the controller managing who's authorized to invoke it. By having the authorization nearby, you follow theory (I forget the name) of 'declare it as close as you can to where you use it.'
It might depend on the background of your coworkers. If they're really used to using something like XML, then I bet they're suggesting some type of configuration file - which seems to be induced due to a more corporate type of programming.
On the flip side, There could be a benefit to extracting out authorization somewhere else (but within the application) so that it's easily modifiable, in case you end up adding a "PaidUser" for example. In that case you wouldn't have to go to every controller to update it. However, I think you end up falling into an all or nothing approach - where it's either in the controller, or it's all in some configuration file. Unless you create a scheme that your central authorization can be overridden by a controller's authorization, except at that point, you can easily lose control of who's managing what and you end up in an 'authorization soup' of sorts.

Resources