0

Posts may be smaller than they appear! Skip the bulleted list.

Lemme Just Say...

I know that this is going to be largely (entirely...) opinion-based. Everyone has their own approach, and their own best-practices ideology, but I'm hoping to glean some thoughts from those who have worked on successful web-apps previously.

There are plenty of resources discussing various MV(X) patterns, but they mostly just detail the interaction between the components, and never seem to dive deeper into separating various components, nesting models within one another, and so on. Hopefully this can become that, and devs will be referencing your insight for generations to come.

The Set-Up

(For ease, I will use "app" to mean "web-app")

Take the following mock app, based on a simplified FB layout:

Mock App Layout

A quickish run-down (for reference, just skip to question below):

Header (left->right)

  • Hamburger Menu
    • May be a drop-down type of menu, or a permanent fixture
    • Some menu items have "data" associated with them (i.e. dynamic values, showing numbers of messages, new items, or whatever)
  • App logo/home-page link
  • Search area
  • Links and btns to profile, home, settings, etc
  • User drop-down menu
    • Standard drop-down (click-n-go)
    • Menu btn is thumbnail img from "my" profile

Main Body (An infinite list of various posts/imgs/videos/etc)

  • Post options dropdown (Report, hide, embed, share, etc)

  • Top area (post contents)

    • Poster profile image/hyperlink to their profile
    • Poster username/hyperlink to their profile
    • Time hyperlink (points to page of similar-time posts)
    • Post comment
    • Image, video, hyperlink, etc from third-party site
  • Bottom area (viewer interactions)

    • Like, comment, share btns
    • "My" profile img
    • Comment text area

      • Text area houses btns to add external media to comment
    • Previous comments

      • User profile img
      • User comment
      • Like, comment btns
      • Likes and time hyperlinks
      • Comment options dropdown (Report, hide, embed, share, etc)

Finally, the Question(s):

These questions are pretty heavy, and I know there is no simple answer shorter than a novel. What I'm trying to get is different peoples' approaches, general rules-of-thumb, and the like. I understand the principles of various MV(X) patterns, but I always doubt myself when implementing, and feel like I'm just hacking stuff together that another developer would be appalled at.

I'm not necessarily looking for an answer to every question-mark that follows (there are a lot...). The seemingly endless strings of questions are more to illustrate the shit-show that runs through my head every time I work on a new project.

FINALLY... Finally, the Question(s):

For even a simple-ish app like above, how many models/views/controllers (M/V/C) is too many? Is too few?

I understand that there is a lot going on above, so let's just look at the top-left hamburger menu for a moment:

  • Is the menu not an M/V/C of its own, and simply a set of components of the Header M/V/C? And the Header handles all menu-related stuffs?
  • Is the entire menu (including the hamburger icon and drop-down portion), a single M/V/C, nested within the Header, inside a wrapper?
  • Should each menu item be its own M/V/C? Or maybe just those with the additional data that needs to be collected, displayed, monitored and updated? And the simple click-n-go hyperlink items are just components of the menu M/V/C?

And then up a level, to the entire Header:

  • Is EVERY element its own M/V/C? Or perhaps only those that are more complex (i.e. menus, search area)?
  • Are the menu btns part of the Header M/V/C, so that the Header controller handles hover/click events? And then the actual menus are their own M/V/C within wrappers in the Header?

And so on...

Yep, a headache. So many what-if's. And the header is comparatively simple, next to the post items within the main body.

Final Thoughts

This is the stuff of nightmares. Seriously, this crap keeps me up at night, trying to figure out how to approach something like this without totally F-ing it up, and leaving it entirely unmodifiable for future devs. The proper/effective execution of these kinds of things could be the difference between an acquisition and going tits-up.

Thanks for making it to the bottom, and thank you for any and all help. I'm not the only one losing sleep over this.

1 Answer 1

2

I think the answer is fairly simple.

Where you have the same thing twice, like your left and right drop down menus, generalise it into a widget and reuse the code. (ie it gets its own View model, View and Controller which are reused)

When you have a thing only once,(ie the header) group all its components into one big view model, view, controller. Or rather, don't worry about splitting it up yet.

SO for your example page I would have the following structure

PageVM Page
    HeaderVM Header
        MenuVM LeftMenu
        MenuVM RightMenu
        string Link1;
        string SearchString
        string Link2
        ..etc
    PostVM[] Posts

With controllers roughly per VM (with MVVM stick the controller actions on the associated VM)

Models are a slightly different problem, in that they should be defined by your business logic/Domain rather than your UI.

I think you might be over egging the pudding to say these choices are so important. Usability, speed of response, scaleability are far more important.

Throw out your clever architecture if you can make it run faster or cheaper

2
  • Thanks for the input, that helps a lot. But, since there is only one header, why did you make it a VM of its own, opposed to assigning its elements directly to the page VM? This is why it's such a headache, trying to figure out the best method. What's the cutoff for complexity and reusability, when to make separate VM, and so on.
    – Birrel
    Commented May 20, 2017 at 15:32
  • because presumably you have more than one page with the same header. even if its just the terms and conditions or login
    – Ewan
    Commented May 20, 2017 at 15:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.