16 ms·
Why I No Longer Use MVC Frameworks
- norswap 11y agoI always find it interesting how something seemingly as simple (conceptually speaking) as building a web app can in truth turn out pretty darn complicated. I'm not seeing all the complexity we see here or in other frameworks is warranted, but clearly there is something going on making this quite hard. I'd be interested to see fundamental research (and vulgarization thereof) on this.
- tracker1 11y agoMaybe because there is more to creating a usable interface that can have multiple points of operation from a user perspective than the underlying data storage or API interfaces. Developers that concentrate heavily on backend data interfaces think their worlds are so important and have spent so much time looking down on the front end that now, when better front ends are demanded, they fall apart trying to create them... The same does happen in reverse, designers tend to want certain types of interfaces and workflows that are simply hard to manage in any practical way. The difference is that now, more people on both sides of the spectrum are starting to gain insight into the rest, and starting to realize that good "full stack" development is hard. There are also nearly infinite options, and even more opinions.
- carsongross 11y agoHe nails the problem: API bloat due to chaotic front end needs, but there is a much, much simpler solution: move the UI/DOM building back to the server side. This gives you a nice, secure environment to build your UI in with the full power of the query language your datastore provides, and it doesn't require any particularly complex architecture or discipline to maintain. And, of course, I would be remiss if I didn't mention my baby, http://intercoolerjs.org/ http://intercoolerjs.org/, as a tool to help you do it.
- bicknergseng 11y ago>>with the full power of the query language your datastore provides If your datastore exists in your server side rendering application. I would say that "chaotic front end needs" exist in applications that require data from multiple data sources: many different APIs and datastores that need to be independently queried. If that is true, is there really a big difference between having a server side or client side view model that wraps that complexity?
- carsongross 11y agoI don't know if I completely understand what you are saying, my comment doesn't rely on multiple data stores. I'm talking about a web application with a single (say, SQL-based) datastore. I am saying that without the full power of that data store on the client side (that is, an optimizable query language, update and insert statements) you will always be thrashing your API around to deal with chaotic UI needs. If you do expose the full datastore functionality on the client side (which GraphQL is a move towards) then you have a different problem: you are exposing your datastore in a fundamentally insecure environment. So you are screwed either way.
- hnal943 11y agoYes in that instance you are correct that server-side rendering is easier. It doesn't make it any easier to build a mash-up application in which you are relying on multiple sources of data that you do not control.
- bicknergseng 11y agoThat's exactly what I'm saying. If you have a web application with only one data source built in, then GraphQL is not for you. In fact, that whole post wasn't for you. You probably should stick with a monolith until you can't. If you have a large, complex web application that integrates data from many different sources, then an API aggregator or view model is essential. GraphQL is not an attempt to move the datastore clientside.
- reitanqild 11y ago
- colemannerd 11y agoCool abstraction, but would love to see actual code implementation.
- jdubray 11y agohttps://bitbucket.org/snippets/jdubray/ https://bitbucket.org/snippets/jdubray/ Can also share more code privately
- xyzzy4 11y agoI prefer the "VC" style (MVC minus the M). It is way too much work to have to redefine your models on both the client side and server side, when you can simply have all the data in temporary dictionary structures. You define your models just once in the database itself. I don't know if anyone else does this, but it keeps the amount of code to a minimum.
- ralmidani 11y agoI use Django on the server, with Ember on the client-side. Without a concrete model layer in the client that has computed properties and, to a lesser extent, observers, things that were trivial to implement would become much more difficult. Of course, I look forward to the day when we can write our models once for both the server and the client, but I've yet to see a "full-stack" solution compelling enough to get me to abandon both Django and Ember.
- softawre 11y agoYou can do this with any Javascript-on-the-backend solution today. Not saying it's better, but we're doing it. Node is the obvious one, but we're running V8 in Java on the backend so we can use Spring-boot and a bunch of other Java stuff we get "for free" at the company.
- sheldonb 11y agoTo be fair, and if I'm understanding you correctly, you can use ember-data alongside Ember to get your model layer (or even just use plain Ember.Objects as needed). Ember fastboot seems like it'll address some of your concerns too - it'll allow for initial rendering of a page on the server with the intention of the client taking over after that.
- ralmidani 11y agoI use Ember Data along with Ember. Ember Data is my model layer. I should have made that more clear. As for FastBoot, correct me if I'm wrong, but right now it supports rendering static pages for SEO. This is not useful for business apps. Rehydration on the client-side (what you seem to be referring to) is still being worked on. But it does not replace the server-side application. At any rate, eventually someone will bring together the best of server and client technologies in one full-stack package. With all due respect to what's out there now, I haven't seen anything approaching the elegance of Ember and Django.
- prewett 11y agoI think part of the problem is that MVC is pretty heavyweight. Most UI doesn't need that kind of flexibility, but when you want it, you want it. So you need a way to make it simple most of the time and still have access to the details. In web development it is probably complicated by that fact that, in my opinion, declarative positioning and sizing of elements is a pipe dream. It looks simple until you try to actually implement it, and HTML/CSS has only a rudimentary implementation. (As far as I know, Motif and Apple's constraints are the only UI toolkits that have a solid implementation) Given what we want to do with the web these days, I think we would be better off with programming the web page declaratively. Something like what Qt does. I've never found an easier way to write a UI than Qt.
- brightball 11y agoYou nailed it. MVC was popularized because after enough people went and just threw together random things for enough projects, turnover, learning curve, switching between projects, etc just became a huge burden. The big sales pitch for MVC on the web (largely influenced via Rails) was a good enough common structure for web apps that developers could learn and apply across projects. It worked in that regard, but as usage became more popular we ended up adding on more and more and more and more to try to make the "common" solve everything. Constant changes screw the entire point of the "we all learned and know this" benefit. Flexibility of your approach is probably more important in the world today than following a rigid structure in an attempt to let the structure solve everything. I like the approach outlined here...but I'd have a hard time using a framework based on it. I'd rather write my own code using a simplified process and minimizing dependencies if I'm going outside of something that's clearly a major player that can be counted on to stick around.
- coliveira 11y agoYou just mentioned something very important: minimizing dependencies. Open source frameworks are sold as a way to minimize development complexity, but they add the big pain of depending on external packages that frequently change without notice. If you develop you own code, at least you know what and how things changed.
- johndubchak 11y agoI believe another major issue arises in the form of the design of these new API's are not designed using the historical knowledge that got us here. It seems to me at least that every 10 years or so a new group of fresh grads enter the workforce and by sheer will (and all nighters) recreate different forms of the same solutions to familiar problems. Meanwhile, the previous designers and implementors seem to fade (who knows where they end up?) and the normal evolution we should be seeing in our API's, frameworks, and collective knowledge simply inches (is that too generous?) along. We are giving different names to original ideas. For example, I have read (sorry, I can't find the links) recently where others have published on interesting new design patterns only to find out they are essentially renamed versions of the original GoF patterns. The same challenges exist and we are seeing someone else's take on the solution and it feels too familiar because they look at what's out there and provide only a marginal variation on a theme. I believe this partly explains this "been there, done that" that we're seeing these days.
- nickbauman 11y agoTraditional OOP/Imperative programming tends to encourage this "reinvention". Where the old guard goes? I think programmers age out when they see the same "trend" for the 3rd time and decide they need to get off the hamster wheel and go into management. GoF patterns make sense if your language is statically typed and OO and you don't have real data abstraction. To be fair, most OOP practitioners don't even know what "data abstraction" means: this is what is meant by "it's better to have 100 functions that work on one datastructure than 10 functions that work on 10 different datastructure. The latter is OO, the former is FP.
- edejong 11y agoYour first paragraph makes some sense, but I truly disagree with your second. Good OOP design is very similar, if not identical, to good FP design. For example: - The iterator pattern: is essential to more abstract FP, see for instance 'the essence of the iterator pattern: https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf' https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.... The iterator as a stream is a coinductive data structure and a such a fundamental structure in FP. Also note that transformations on iterators are applicative. Then, look at many of the other GoF structures: the visitor pattern, which is very similar to recursive algorithms on trees. The adapter is basically applicative, the Factory is difficult, but could be seen as a coinductive structure. Also, one should note that in (modern) proper OOP, composition is your most important tool. This is very similar to composition of functions.
- lhorie 11y agoI feel like this is one of those cases where someone rejects currently existing tools, but then goes on to throw out the baby with the bath water when trying to come up with an alternative. Figure 7 (http://cdn.infoq.com/statics_s2_20160209-0057/resource/articles/no-more-mvc-frameworks/en/resources/fig7.jpg http://cdn.infoq.com/statics_s2_20160209-0057/resource/artic...) looks to me like the sort of MVC you would do with vanilla PHP or friends back in the day. In figure 9 (http://cdn.infoq.com/statics_s2_20160209-0057/resource/articles/no-more-mvc-frameworks/en/resources/fig9.jpg http://cdn.infoq.com/statics_s2_20160209-0057/resource/artic...): he handwaves saying that you can compose things, but nothing in the article suggests that SAM provides better mechanisms to sync data between client and server. E.g. what if the view is a table, and the action is deleting an item? Does an update consist of re-downloading a whole new table worth of data? Would it also do that if I deleted that same item from some other view? Or does it require 2 http requests in series (a DELETE followed by a GET)? What would an undo action look like in terms of HTTP requests and responses? The graphs feel like they're largely meaningless. Having arrows in a diagram pointing from one word to another doesn't say anything about the complexities of the system.
- carsongross 11y ago> I feel like this is one of those cases where someone rejects currently existing tools, but then goes on to throw out the baby w/ the bath water when trying to come up w/ an alternative. Humorously, this is exactly what the current set of client side MVC libraries did.
- lhorie 11y agoNo offense, but I think it's disingenous to compare the SPA movement with a guy with vague graphs that look like they suggest going back to what people used to do 5-10 years ago. The SPA movement "threw out" the notion of ajaxing HTML snippets in favor of ajaxing structured data for many reasons: better separation of concerns, better asset cacheability, better defaults against XSS, better infrastructure for multi-client architectures, the list goes on. I'd argue that security w/ data endpoints is far easier to audit and reason about than the old school RPC-style send-me-html-when-I-do-X server interfaces.
- al2o3cr 11y agoFrom one of the screenshots: div class="opacity-'+slider.maskOpacity Even better once you notice the actual inline `style` attribute two lines up. headdesk
- tommoor 11y agoIt's almost as if just about anyone can write a blog post on the internet :)
- soundoflight 11y agoI've worked on proprietary frameworks very similiar to what the author describes. They are great for the web and in my opinion allow for tighter code. The issue is that I haven't found a good, open-source one for the web. Also, interesting, is the fact that computer engineer "coding" is much more into the state concepts brought up in the article.
- scotty79 11y agoI'm not sure why author dismisses graphql. It greatly simplifies server-side work. You just need to implement one endpoint that responds accurately and quickly to a composed query in accordance to what rights the current user has. It's not as easy as "serve result of SELECT *" but it's well defined and flexible for consumers.
- c17r 11y agoAgree. His opening complaint is from the Front End saying "I need x, y, and z so make me an API that returns {x, y, z}" which he wouldn't need to do for them if they were using GraphQL.
- weq 11y agoIQueryable. Go look it up. MS did GraphQL years ago. If you got out of your insurlar JS/FB/Twitter bubble, u will see the anti-pattern that IQueryable become.
- scotty79 11y agoI don't think IQueryable is very composable. It goes bit beyond simple query builder because it can automatically translate for you more expressive queries into SQL (http://www.infoq.com/presentations/theory-language-integrated-query http://www.infoq.com/presentations/theory-language-integrate... ) But I don't think people could define parts of IQueryable in .ascx files and compose it into single IQueryable result of which feeds the components. That's the main idea of graphql.
- hokkos 11y agoGraphQL is "structurally typed" where IQueryable is nominally typed by its generic argument. This make GraphQL more easily composable, but IQueryable is still composable with functions.
- keithwhor 11y agoIt can be as easy as "serve result of SELECT *". We're working on it with Nodal. http://graphql.nodaljs.com/ http://graphql.nodaljs.com/ - some pretty neat progress so far.
- halayli 11y agoHe starts with a negative tone when describing react & redux without backing up his negatively with proper & convincing arguments just so that later he can throw in his alternative solution. I don't know why we keep doing it but often times we cover our eyes on purpose and brush off existing solutions backed by thousands of engineers so that it's easier to make our points.
- Lazare 11y agoEspecially considering his proposed solutions looks an awfully lot like not-very-fleshed-out remakes of React and Redux.
- jdubray 11y agoThis is not true, please visit the SAM room on Gitter https://gitter.im/jdubray/sam https://gitter.im/jdubray/sam In a nutshell: in redux the reducer updates the model as: state.counter += 1 ; All SAM suggests is that this is an unfortunate coupling, you should write it as: // action function increment(value) { return value + 1 ; } and then present the output of the action to the model: state.counter = data.counter ; Redux does not have any next-action-predicate either.
- halayli 11y agoThat's not true either. In Redux the reducer is always pure and never modifies its arguments, at least in principle. It returns a new copy representing the new state. Dan Ahramov relies on deep-freeze to always assert this fact in all of his tutorials. Regarding next-action, in Redux subscribers are called after the root reducer returns the new state. You can always call dispatch from a subscriber. You and Sam are proving my point by not actually taking the time to understand the existing solutions.
- veenified 11y agoTake a look at this boilerplate project (https://github.com/erikras/react-redux-universal-hot-example https://github.com/erikras/react-redux-universal-hot-example)... I think Redux with the multireducer lib removes that coupling you speak of.
- wereHamster 11y agoWTF? Blindly concatenating strings... hello XSS..
- phantom_package 11y agoIsn't GraphQL/Relay (or similar tools) the solution here? Has the best of custom endpoints (can be conceptualized as a single, infinitely customizable custom endpoint) without the drawbacks (there's only one endpoint, and backend engineers just need to expose a schema). It was kinda disappointing to see him fail to properly address tools that were designed to resolve his original concern. He basically decides that GraphQL forces you to "shape your models to your views" (which is false, GraphQL/Relay just collates and trims your models before delivering them to your views). In a sense, it allows him to continue to say "yes" to his frontend developers (which is good from a product standpoint) without adding a ton of custom endpoints.
- romanovcode 11y agoThe reason I choose to work with MVC frameworks is because more often than not other people work on my code with me. If I would create my own abstractions it would be good for me but very, very bad for others.
- velox_io 11y agoChanging the API design because a frontend dev doesn't like the style is definitely an anti-pattern. Customising APIs for every imaginable use case will get painful fast! Angular does have powerful services to transform objects. For example last week a library (ngTagInput) was expecting a list of objects with {id, name} however the server was returning a list of integer id's. It was trivial to replace the id with the {id, name} object in the service, without requiring changes to either the library or the back end - the API is still generic.
- plaguuuuuu 11y agoAPIs should be designed such that the total effort to build both sides of the equation is minimised. APIs are, after all, designed for consumption - you can return data in any number of formats - eg a proprietary binary format, or whatever, but if your consumers find it hard to use, then the API sucks. End of story.
- mettamage 11y agoCurious to what extent you stand by this statement -- as an exploration not a refutation ;) So lets stretch it to the limits. Lets create an API for a non-programmer. For example, lets allow him to make a survey in iOS. You could, for example, create an Excel file -- lets assume these non-programmers know Excel a bit. One column could designate a template, another column could be used for the question. Perhaps a column for materials (e.g. video files or images). I guess the point is clear, you could make columns that do something specific in the app. Add some documentation and presto, you have an API for non-programmers :) The Excel file itself could be given to a programmer who implements it or it could be uploaded to some automated process that spits out an iOS app. A rudimentary version could for example attach some pre-specified views with some questions and images. What do you think, is it possible to create an API for non-programmers via some software that they do know?
- abledon 11y agoThis was a sobering read.
- pearjuice 11y agoIt's a typical Hacker News cliche: "Why I No Longer Use [commonly accepted standard]" but I am honestly glad that the author put a lot of effort into explaining the theoretical AND practical concepts behind his stance. So in case you skipped the article because it fell through your "textbook HN hit" filter, please take my word for it that it's worth reading.
- djfm 11y agoCan't really see how the proposed solution is different from React + Redux.
- sbov 11y agoI feel like part of the "problem" of API churn is because we are writing APIs that live in the controller layer. Just because it runs on the back end doesn't mean it lies within the model layer. Beyond that, it certainly makes for less code to make the model directly line up with the view, but you create coupling between the two. This seems like a major difference between MVC I've experienced in the web vs desktop apps back in the late 90's - in a desktop app my view didn't rely on the model's code, just on the model's data. But nowadays with rails and spring and django the view is coupled directly to model code.
- mej10 11y agoIf you are serious about front-end Javascript, you owe it to yourself to check out the ClojureScript libraries Reagent (and re-frame) and Om.Next.
- pandeiro 11y agoAside from the pithy syntax compared to even the most futuristic ECMAScript, meaning frontend code is faster and easier to write (and throw away, if need be), there's another key element Clojure brings to solving this API proliferation problem, which is just how easy it is to do data transformations. The Clojure standard lib makes it trivial (dare I say, fun?) to carve up and reshape whatever data you're consuming to fit the model your application needs.
- joesmo 11y agoYeah, I feel that the real innovations in UI programming are happening in ClojureScript right now based on top of React which is really a very low-level dependency. Javascript is mainly copying what's happening there with libraries that allow you do do reactive programming (like RxJS), have immutability, etc.
- fabrigm 11y agoBecause you have time?
- drostie 11y agoSearching through the comments here, only one of them mentions SAM, which is the point of the article. Some nuanced thought about what's going on here is therefore warranted. So let's start with old-school Smalltalk's MVC: this was a message-passing system consisting of three types of concurrent processes: * models maintain a list of "subscribers" that they regularly send certain messages to, in response to the messages that they receive from the outside world. This can as always involve the internal state that each process maintains. * views subscribe to models and then present a graphical description of the messages they receive. * controllers listen to user-interface events from the view, and use it to send messages to models. These have transformed mightily in the intervening years; a model these days often refers to some form of schema for data structures which are returned by services; controllers often query those services and provide them to the view; views may define their own service-queries. Often there is no clear notion of subscription except possibly subscribing to events from the GUI, which is the responsibility of the controller; the controller basically handles everything which isn't either the structuring of data or the organization of the display components. SAM appears to be coming from the latter developments and is concerned with an associated explosion: Every view and interaction more or less gets its own service on the back-end, providing a sprawling codebase which resists refactors; they also get their own controllers which maintain them. In the SAM idea, the model now reprises its earlier notion of managing subscribers and containing business logic: however it is now "dumbed down" from its potentially-very-general Smalltalk definition: the model is instead meant to hold and maintain a single data-structure. (Can there be multiple concurrent models?) The model apparently only receives requests for an all-at-once update, but it may decide to transform its state `new_state = f(old_state, proposed_state)`. Presumably then it again tells its subscribers about the new state if it is not identical to the old state. (Each view is expected to compute the diff itself, probably?) A "state" in SAM appears to be identified with a "view": a "state-representation" is a function from a model to a DOM. Your GUI consists of a bunch of these, and hypothetically we can diff the DOM trees to better understand what needs to change on an update of the related model properties; the "view" is basically just a bunch of representations of the underlying state with some "actions." These "actions" are not actually parallel processes at all but do take the classical responsibility of the "controller", routing user-interface events to messages to send to the model. The apparent point here is that they should correspondingly be very "dumb" controllers: they just create a transformed version of the data that they received from the model and then send it back to the model as a "nomination" for a possible change. Finally there appears to be a strange next-action callback which may be part of every "view update." (It's not clear where this lives -- in the "action"?) I am not entirely sure why this exists, but it may be that the algebra of actions without this callback is merely an applicative functor, not a full monad. The essential idea here is that the function apparently can compute a follow-up action if such needs to happen. If I'm understanding this correctly, then a simple app which seems relatively hard to structure this way would contain: * a counter stored in a database, * a button which should ideally increment that counter, * a display showing the current value of the counter, * a notification window telling you when your click has updated the counter. I'm using a counter since it's got a nice algebra for dealing with coincident updates; if someone else updates the counter then your update commutes with theirs, saving the client-side complexity. Without a framework, we would simply define two endpoints: GET /count (or so) gets the current count; POST /increment will increment the current counter and will say "Success! The current count is now: ____", telling you what you changed the count to. Here it seems like you need three models. First we have the server-side model of what's going on: server model Counter: private count, Subscribers message increment(intended_count): if intended_count == count + 1: count += 1 Subscribers.notifyAll() return ('success', count) else: return ('failure', count) message count(): return count The requirement that we only nominate new versions of the underlying data-structure means that we cannot just define the appropriate increment service which always succeeds, but must instead tell the client that the request has failed sometimes. Then there are two models on the client side: one holds a list of outstanding requests to increment (updated by actions, retrying any failures) and the other one holds the currently-cached value of the server-side data (because we need to update this by both the former client-model's update events as well as by some automatic process). You would probably condense these in practice into one model, however they are different concerns. The former model, however, is absolutely required, as it provides a way for the "notification window view" to appear and disappear when one of the requests has succeeded. This seems unnecessarily complicated given the simple solution in terms of two API endpoints -- however it does indeed fulfill its desire for lower API bloat and some separation of concerns.
- jondubois 11y agoNot using an MVC framework is often fine if you're working alone on a project but you might just end up reinventing angular... Then when new people come in to your project, the learning curve for them will be steeper than Angular - Also you won't be able to hire any 'batteries-included' programmers because nobody will know your framework when they join your company. Worse, engineers might refuse to join your company if they see that you've built a custom solution from scratch... Chances are that your framework won't be as good as Angular or React. Maybe you should try Google's Polymer framework? I've tried all the major ones and Polymer is the least 'frameworky' one.
- matzipan 11y agoAlso, you won't benefit from the ready-made modules that are available out there.
- EGreg 11y agoReading this I am kind of happy we rolled our own framework and dogfooded it for the past 5 years. It has only a few concepts: * Pages (webpages) * Tools (components) * Events * Users (accounts) * Streams (data) Everything is accomplished around these basic concepts. http://qbix.com/platform/guide/features http://qbix.com/platform/guide/features
- onion2k 11y agoThat's always going to lead to a solution you like (because you built it) but it loses the advantages of open source in both "many eyes" where the code gets massive amounts of testing and "prior knowledge" where you can recruit new people who already have some knowledge of the technology you use. Neither of those are necessities, of course, but they're definitely useful advantages.
- dclowd9901 11y agoFirst, his rocket example won't even work (in the actions.decrement function, "'model' has not been declared"), but what he's talking about isn't actually new in React land. https://github.com/chenglou/react-motion https://github.com/chenglou/react-motion Not that every idea has to be novel, but I think the code in this repo provides a far better example of FRP (which SAM is) than that article.
- franciscop 11y agoThere's an excellent tool to avoid the default value mess shown there: defaults https://github.com/tmpvar/defaults https://github.com/tmpvar/defaults It will fill your option object with the data if it's undefined
- carterehsmith 11y agoAlso, if he ever needs to check if a variable is a number, there is another one-line-of-JS project on npm that does just that!
- franciscop 11y agoBut it isn't one line: var clone = require('clone'); module.exports = function(options, defaults) { options = options || {}; Object.keys(defaults).forEach(function(key) { if (typeof options[key] === 'undefined') { options[key] = clone(defaults[key]); } }); return options; }; Besides the tests and the fact that someone is maintaining it. It's not much, but it's code that doesn't have to be maintained by you
- jkcxn 11y agoYeah even _.extend
- pluma 11y agoFirst he dismisses React, then he says his code is looking a lot like React without the ceremony, then he shows code samples that look a lot like React except they use string concatenation (hello XSS) to build the DOM (goodbye DOM diffing) and instead of following the modern React idea of small composable components they are huge and bloated. Is this satire?
- marrs 11y agoI thought he was quite positive about React, but he seemed to be uncomfortable with their lack of provision for the model layer.
- hyperpape 11y agoI was intrigued enough to look at the source of his Star library (https://bitbucket.org/jdubray/star-javascript/src/5806219be6d37bfed9fbba9122e0d8f6de584140?at=default https://bitbucket.org/jdubray/star-javascript/src/5806219be6...), and got very little out of it. Aside from a few truly strange things (https://bitbucket.org/jdubray/star-javascript/src/5806219be6d37bfed9fbba9122e0d8f6de584140/src/core/exception.js?at=default&fileviewer=file-view-default https://bitbucket.org/jdubray/star-javascript/src/5806219be6...), it's just generally not commented or documented, and I have a hard time figuring out how it serves the goals of that article. I'll take another look later, but I'm curious if anyone else got much out of it?
- jdubray 11y agoI am happy to walk you through, here are some links that show how I got there: http://www.ebpml.org/blog15/2014/12/tla/ http://www.ebpml.org/blog15/2014/12/tla/ http://www.ebpml.org/blog15/2015/01/tla-the-die-hard-problem/ http://www.ebpml.org/blog15/2015/01/tla-the-die-hard-problem... http://www.ebpml.org/blog15/2015/01/state-machines-and-computing/ http://www.ebpml.org/blog15/2015/01/state-machines-and-compu... http://www.ebpml.org/blog15/2015/04/star-based-component-model-with-tla-semantics/ http://www.ebpml.org/blog15/2015/04/star-based-component-mod... http://www.ebpml.org/blog15/2015/06/sam-the-state-action-model-pattern/ http://www.ebpml.org/blog15/2015/06/sam-the-state-action-mod...
- mongosucks 11y agopub/sub is the best, call it command bus, call it Flux, Redux,...
- Lazare 11y agoAh, but my version of pub/sub is much better than the others, because they don't adhere to the fundamental principles of pub/sub which I have derived[1]. [1]: I have discovered a truly marvellous proof of these principles, which this comment is too small to contain.
- kensign 11y agohttp://aurelia.io http://aurelia.io
- jijji 11y agoThe problem with MVC is that there is no clear definition of what it is, and so what you're left with is people who are putting code in the View, code in the Model and code in the Controller. Then, go try and debug that. You wind up having to logging basename(__FILE__) to understand what file is responsible for what. It is a nightmare for debugging. Then you have to to talk about the elephant in the room -- performance. Performance using MVC frameworks is orders of magnitude slower than using straight procedural or functional development. It should not take a rocket scientist to understand that calling a function directly is faster than instantiating an object and then abstracting an abstraction from an abstraction from abstraction just to return a result. I dont know why people do it, but I find myself cleaning up the mess more often than not. You cannot convince me that a 10x decrease in performance and a 10x increase in code complexity is a good thing.
- deleted 11y ago[deleted]
- Gratsby 11y agoPeople have a hard time with MVC because frameworks that use the phrase MVC are always more complex than necessary. There's a simple set of separations that you need to pay attention to for your code to be what I like to call "not stupid". 1. Separate your code from your data. You shouldn't be kicking out HTML with your code, like this guy does in figure 1. When you combine HTML or any display information with code that means your designer is your coder and your coder is your designer. Designers suck at code. Coders suck at design. Keep that shit separate. 2. Separate your logic code from your code that changes your data. You shouldn't be running updates/saves/inserts from 30 different locations in your code. Define your interface, expect that interface to work. When you need to shift from Oracle to Redis to RDS, you shouldn't have to refactor 80% of your application. You refactor your data update code and leave everything else that works alone. There you have it. Model, View, Controller. You have a data model that can be displayed in any number of ways, and you control CRUD on that Model via the controller. It's not a religion. Just make sure there's a logical separation within your code so you can delegate as your team and application grows. Architect things logically and call it whatever you want.
- jdubray 11y agoSorry, but you just don't get the fact that SAM is reactive/functional and what benefits you can drive from it.
- falsedan 11y agoPlease colleges, please make computer science/software engineering students take at least one course where they have to write essays to pass the course.
- mettamage 11y agoThey don't, unfortunately. In my case I was very lucky. One of the first things I did was Google about what programmers would do -- as opposed to programming which I was scared of in the beginning days -- and I found out about Joel Spolsky very early on in my studies. Getting a bit of breadth about the culture and more about the philosophies and theoretical underpinning, from various writers, has been quite helpful to me. This is what he said: http://www.joelonsoftware.com/articles/CollegeAdvice.html http://www.joelonsoftware.com/articles/CollegeAdvice.html You may guess what his number one tip is ;) My number 1 'hack' that I learned from these classes is to eliminate every unnecessary word and be as short and concise as possible. That way, I make fewer mistakes, get my point faster across and I communicate more clearly in general since there's no risk of being long winded. I never do it in HN comments though, it takes a lot of time.
- falsedan 11y agoMy number one hack is to take the conclusion from the third paragraph/wherever and, since it's the most important thing to communicate, move it to be the first part (in front of all the tedious "here's the background on the problem we were trying to solve").
- LAMike 11y agoI think the author might like the simplicity of something like Vue.js
- andraganescu 11y ago<< As a veteran MDE practitioner, I can assure you that you are infinitely better off writing code than metadata, be it as a template or a complex query language like GraphQL. >> Reading it is worthwhile if only for this phrase.
- known 11y ago"Premature optimization is the root of all evil" -- Knuth
- ciscoheat 11y agoIt happens time and again, another pattern from the programmers perspective, when MVC really is much more than a pattern, and it includes the users perspective. It's not about separation primarily, that's the nerd's view. I've made an attempt to clarify what MVC is really about. It was posted here before, I appreciate if you read it: https://news.ycombinator.com/item?id=10730047 https://news.ycombinator.com/item?id=10730047
- emergentcypher 11y agoI don't think MVC belongs on server-side web frameworks at all. It's not a continuously updating interactive display, it's a one-off thing. You don't have a model object sitting around sending messages to the view when it updates. This doesn't happen. There is no triangle of messaging. What really happens is a request comes in, and your "controller" is the one doing all the calling. The HTTP server is by its very nature a pipelined or layered application. Requests are turned into responses through a series of transformations. They go down the layers as they work their way to your database, and back up the layers as they are built into responses. This is, incidentally, why functional programming is such a great fit for web servers.
- dh997 11y agoControllers are important for being gatekeepers, which can be adjusted (think middlewares which add security, logging or other changes uniformly) and inspected outside of the MVC code, and separates outside from inside. It might be worth the tradeoff in the short-term, but it's the lifecycle TCO of code counting support and modifications over many projects which will validate or invalidate a particular approach (there is also a cost in terms of hiring and learning curve for inventing an alternate convention). I hope it works out.
- ivan_ah 11y agoI'm not super convinced OP's SAM architecture is that revolutionary. It will take something waay better to displace the current champion: React+Redux. And speaking of the champion, here's a good write up[1] about tfb's helper library 'react-redux-provide' that automatically matches names in this.props with Redux actions and reducer outputs. It's a simple thing, but tremendously reduces the wiring boilerplate for React+Redux apps. [1] https://news.ycombinator.com/item?id=11098269 https://news.ycombinator.com/item?id=11098269
- niutech 11y agoMVC, in a strict sense, as in Gang of Four, almost does not exists in JavaScript frameworks. What we see is MVP (Backbone.js, Riot.js), or MVVM (KnockoutJS, AngularJS). ReactJS prvides just a View.