I recently took first steps using the MVC pattern. While coding along, I was reflecting on the idea of separation of concerns, which made sense to me and turned out to be really helpful in my coding.
Nonetheless, I was asking myself a few practical questions:
- Would you consider it bad style if the controller accessed information directly in the model instead of using a get/set method?
class Model {
data = data;
}
class Controller {
doSomeControlling = function() {
model.data += 9;
}
}
const model = new Model();
const controller = new Controller();
- Assuming my model is obtained from who-knows-where (e.g. a database), should I include a fourth element dataHandler between model and controller? I am thinking about ensuring that if the database changes, etc., I still have the possibility to retain my model. Or should I rather implement model-get/set-methods that handle exactly this?
class Model {
data = ...;
}
class DataHandler {
getDataFromADatabase = function() {
// lots of database connection stuff
return data;
}
}
class Controller {
setData = function() {
model.data = dataHandler.getDataFromADatabase();
}
}
Further questions about structure unrelated to the heading
Does it make any sense to implement e.g. a controller as a class, when you are anyways going to instantiate it right away, and only once? (see last two lines of first code sample above)
How extreme should you be with methods? I can find a method for lots of small bits that might make the higher-level-function a lot easier to read, but adds lots of methods which would more or less only be used once. Or in other words: When is enough enough? :)
Thank you for your thoughts!
Photo by Mihai Strompl on Unsplash
Top comments (2)
No, I would not. Although this is hard to answer without having a holistic picture of the rest of your MVC pattern. MVC has a number of adaptations. And I think ultimately pragmatism should win out. If there turns out to be a valid reason to enforce a more rigid separation, then you will discover it and know better for the next time.
This is an excellent question. You've observed that there are differences in the needs of different consumers of the data: e.g. display vs decision vs storage. And something extra is required to account for those differences. A common solution is to have one main data source and mapping it into a form needed by the consumer. (I believe this is the purpose of
dataHander
in your question.) A less common solution is to store data in different forms suited for different consumers. There's no right answer, only trade-offs that you must weigh.This is part of an object-oriented design. You probably should not notice any real performance issue unless you are doing performance-sensitive work. Functional programming would do it differently where controller methods are static. But there would instead be extra memory usage / instantiations of data due to immutability.
Separating out discrete bits of logic into named/private functions can improve readability, even if they are never reused or exposed outside the object. However, this can be taken too far. If I need to trace through a spiderweb of methods-calling-methods to figure out what actually happens... that's not readable either. Personally I tend to spell everything out first. Then if it reads as too tedious, extract out some isolated details. It is much like writing literature. It is important to give the reader enough detail to understand the steps without bogging them down in minutiae.
Dear Kasey,
thanks a lot for your detailed response. It gives me good clarity on how to proceed and where I need to spend more time learning.
Kudos!
Sebastian.