I having trouble figuring out the correct architecture for this kind of application: it's a diagramming application, which resembles MS Visio. The diagrams are used to generated data which is passed to another application.
When designing applications, I've always tried to used layering, but now I can't decide how to do this when the data is so tightly coupled with the presentation. For example, a certain object in my canvas has a (X,Y) data, which is used for presentation purposes only, but has to be stored like domain data.
Where I'm getting things wrong? I'm pretty sure I'm looking at this from the wrong angle, but I can't figure out the right one.
Thanks again!
UPDATE:
I'm also aware that maybe I shouldn't be separating UI from domain in this case. If that is so, please provide me with some rational of when to apply separation and when not to.
In a diagramming tool the x/y position of a shape is part of the domain data (the location of the shapes is part of the diagram - you cant draw the diagram without it), the code that use those x/y coordinates and draw a shape on the screen is part of the presentation tier.
I know some people think that data that is only used for display should be saved separately, but in every project I've ever worked on that saved data separately this turned up to be a huge maintenance and support nightmare.
In a simple diagramming tool (if the tool just draws and edit the diagram without any fancy processing based on the diagram) there is no business logic, there's only the code that draws and edit the diagram (that belongs in the presentation tier) and the diagram data (that is the domain model).
If there is no business logic, by using a separate set of objects for domain and presentation you'll have to duplicate all your model data twice (once in the model objects and once in the presentation objects) and you won't get any advantages from separating the business logic from the presentation (because there isn't any).
On the other hand, if you do have some algorithms you run on the data you do have something to gain by separating the graph data from the drawing code - you can run the algorithm outside the tool, you can have better automated tests, etc.
also if you write another system that operates on the same data you can at least share the model definition and save/load code if you separate it from the drawing code.
So, let's summarize:
All the diagram data is part of the model (including data only used for presentation purposes).
Anything that draws to the screen or handles user input is in the presentation tier (obviously).
If those two cover all your code and data than your application don't have any "business logic" and the tier separation is probably overkill.
If you have any code that doesn't fit into those two categories and you think it should be part of the model than you should build the two separate tiers.
If there's any chance for code sharing between systems you should make sure the shared code is not mixed in with the presentation code.
And one last "bonus" point - if this is a project that's likely to be in active development for a long time with new features added in the future - you may want to separate the UI/data anyway just to make future work easier - you have to decide if this future saving is worth the extra time now and if this separation is really likely to help in the future.
I think you need to make sure you're keeping the what and the how separate. What you are displaying is abstract, sets of coordinates, shape types. How you're displaying it is very specific. I'd make sure the domain model dealt purely with the what and the view layer dealt uniquely with the how. It's hard to get into specifics though without knowing more about your app.
You could try to implement some kind of view model, which saves the current layout of your objects. This way, x/y values together with the id of the object are stored in a layout file while pure model data is stores elsewhere.
Maybe this helps a bit,
Related
I have a view that I may use in any number of applications. It's a special viewer for a kind of data type. It contains a special reader for files that pertain to this data type and it can write them. What are the pros and cons of doing it this way? In a recent project, the MVVM proponents argued the view must be "dumb". This makes no sense because how can it be dumb if it is a narrowly specialized viewer? Is it possible that MVVM comes from the web world where viewers are simple? Anyway, the MVVM proponents also believed any data that goes into a view must be conditioned first e.g. converted to HTML, if the view is a webview. Seems like overkill. Why do that?
The concept of MVVM is to separate business logic (model) from view. In your case the reader writer should be in the model code. The Pro is that if you at any point want to make changes to the view side you can do so without changing or moving around code that does the actual data exchange (read write).
It also means that you can write tests against your model and if you change your view the model and test code will be left untouched.
Con with MVVM is that it adds some extra layer of code, it can add some development time (at least when one is new to MVVM) and in the beginning one may feel a bit locked by follow a pattern.
In the end I usually find the Pros to be bigger. One get a good and well thought through Design, separation of concerns for the codebase, easy to test different parts and the day you get a request for modifying or extending the control it will be much easier.
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.
Overview
I’m building a simple web application consisting of a canvas and elements on the canvas.
The canvas supports the following operations: load, save
The elements support the following operations: move, resize
JavaScript on the web page sends a message to the server for each operation and the server sends an appropriate response.
My design
Note: the arrow between the Canvas and Element objects is supposed to denote that the Canvas object contains a list of Element objects. I didn't have the right symbols for the diagram.
Example work flow
An element on the canvas is moved generating an element_moved message.
The front controller manages the session and passes the message to the canvas controller with the correct canvas object.
The canvas controller inspects the message and sees that it is for an element on the canvas and passes it on to the element controller.
The element controller parses the message and updates the appropriate element object directly.
Question
Is this hierarchical arrangement of controllers common place in MVC designs or am I completely missing the point? I've searched for several hours but haven't found any sites which discuss MVC design in more depth than simply returning a page view.
My motivation behind the design was that each object that the client needs to interact with has a controller so that if the interface changes (to support new methods) then the corresponding controller can be updated without impacting the other parts of the design.
usually you won't have one controller calling another in MVC. What you have specified as Element Controller is really just a part of business logic to update the canvas model. If your use case requires you to update the elements independently of the Canvas, then you will have a separate Element Controller, calling the business logic to update the element.
Cheers,
Ryan
Your situation raises fundamental questions when attempting to organize concerns in client-side JavaScript for MVC.
First Fundamental Question
1) Should the entire "page" use one monolithic Controller, where member methods of such a Controller are the event handlers / starting points for working with a single Model and a single View for the entire page?
In regular expression speak ...
Controller{1}
Model{1}
View{1}
Since there is only ever one Controller, there is no ambiguity in the idea that its methods must serve as the event handlers / listeners for input into the scheme: Controller.moveCircle().
Playing dumb for a minute, if there is only ever one Model, then you can simply go to one place to create all the data / state handling methods that you need. Right? (hehehe) ;-) Model.calculatePosition(), Model.calculatePrice()
In the most basic client-side / web scenario, if there is only ever one View, one might think just putting all presentation logic there could get the job done: View.repositionCircle(x, y), View.repositionTriangle(x, y)
Discussion 1
Why might a monolithic Controller, Model, or View scheme like this be problematic in the future?
Can I transfer individual screen elements and their behaviors to other "pages" without any hassle or extra baggage?
Coupling and Cohesion
Think coupling. Does a monolithic Controller loosely or tightly couple accessing screen targets?
Think cohesion. Does a monolithic Controller group behaviors / methods related to accessing an individual target strongly or weakly?
Would Controller.moveCircleUp() and Controller.moveTriangleUp() be dealing with accessing one screen target, or two?
In this case, broad questions like these about a monolithic Controller would also apply to monolithic models and views. A Model is most likely composed of several objects for doing and dealing with the data / state of various things, so there's generally less confusion about it's place.
Yet, if it is a monolith too, then it must deal with the data / state of all screen targets. Even with using multiple object properties and multiple methods in such a model, that could get messy.
Re-usability and Maintainability
What I have written about here cannot be good for code re-usability and maintainability. Even if you are no SOLID expert, it is easy to understand why monoliths tend to violate the Single Responsibility Principle. You should not be in the same place to change something about a circle, where you also make changes for a triangle.
Why? Think of it this way. You are floating in the ocean after your boat capsizes. It is you and another crewman. Would you rather be joined at the hip, so that if he loses consciousness, he or she takes you down too? No, you would want to be independent of the crewman so that you are free to sink or swim on your own.
If you are coupled at the hip, you might hit each other in the face or make some other error that would not have happened if each was a single floater.
In other words, it is better to operate independently and work together, than it is to be joined at the hip and try to accomplish the same things. It is not about when things go well. It is about when thing go wrongly, or when independence is preferable. For example, when one is able to grab a rope ladder dangling from a helicopter, but the other is getting gnawed on by a shark.
You want to be able to reuse application elements in different screens or applications altogether. This is why loose coupling and strong cohesion are fundamental to object-oriented programming, and programming generally.
(**Note: View does not mean HTML only, even if this is the most common end result. Other possibilities include SVG, XML, Canvas graphics, image formats ... anything that fits the circumstance.)
Second Fundamental Question
2) Should each crafted, actionable object / element / target on the screen have its own Controller, Model, and View?
In regular expression speak ...
Controller+ (one or more)
Model+ (one or more)
View+ (one or more)
Discussion 2
Do you want to use screen targets / elements on other pages / screens and bring their specific behaviors with them?
In the first scenario, there is a 1:1:1 relationship between Controller, Model, and View. They are monolithic. There is one screen / webpage. In that setup, you cannot take a circle and put it on another page / screen without bringing along the logic for triangle, too!
If the goal is to make code reusable in another context, then the answer is that each shape requires a self-contained MVC arrangement. Each target would have its own Controller, Model, and View.
In effect, this would mean each screen element that you designate worthy would know how to accept input from an event, process it, and show the output. Some how, we made it back to something that sounds rather fundamental.
Final Thoughts
If one accepts the the above as true, then shapes are, well, alive. :-) They are independent of the context. Manipulating them should not depend on the some all encompassing, JavaScript, FrontController, event handling overlord to be triggered first, only to delegate the work to a method of the target's individual Controller.
PHP MVC
Server-side PHP uses the FrontController scheme before getting to the desired Controller sub-class because if you have a single point of entry into the application (/index.php), you have to translate (route) the HTTP request (/contact/send) into an instance of a Controller, and call the desired method from that controller: ContactController->send().
Performance
The real issue here is how well will the application perform after having downloaded and loaded all of the JavaScript into a user-agent.
Answer? The more you have going on, the more memory you will use. If each screen element has a minimum of three (3) files for its Controller, Model, and View, then ten elements could mean thirty (files to download) at minimum.
Of course, other configurations are possible, but that is where a tool of some sort might come into handy to concatenate and minify everything. In JavaScript, I would rather develop one object per file.
I hope this helps!
What is the difference between a presentation layer and an user-interface?
They are close in execution, but they come from different directions. They aren't well defined, depending on the specific context, they may be almost identical or overlap only slightly.
Presentation layer is term in the taxonomy of code and associated resources.
User Interface is the implementation of the intended User Experience in terms of page layout, page transitions and page control elements. (I am using "page" loosely here - you can replace it with "form" or "window").
The distinction is important when you consider how a user interface gets created. If you come from the code, you are basically working with the needs and mechanisms of the code - what data is there to show?, and in what ways your code can change that?
If you come from the user, the questions are rather what data the does the user need? and what data the user wants to change?
(The first one isn't necessarily worse - it's perfect for users who have a good idea of the inner workings of the application, and it makes it often easier to make use of the full capabilities of the code.)
The link in the John's answer refers to the OSI model, which is not the term intended here IMHO.
I think presentation layer and UI are overlapping concepts, though not 100% overlapping.
Form one angle:
The term presentation layer suggests a layered structure in the application, while the term UI does not suggest anything about the inner structure of the application.
From another angle:
The term UI might only include the collection of controls and their event handlers, while the term presentation layer could include some deeper non visual parts of the application like ViewModels or Presenters.
The presentation layer delivers information to the application layer for display.
The presentation layer, in some cases, handles data translation to allow use on a particular system.
The user interface shows you the data once the presentation layer has done any translations it needs to.
More here: http://en.wikipedia.org/wiki/Presentation_Layer
Here's my own interpretation:
Presentation layer loosely refers to the layer which is responsible for somehow displaying the data for the users. It is often spoken of in the context of a software architecture along with other layers such persistence layer, business logic layer, etc, and rarely by itself.
User interface simply refers to the point of interfacing between the users and some software programs. User interface do not always have to have a nice graphical windows capabilities. A console program, one which runs on the prompt, is also said to have a user interface, just not a graphical one.
I've read a statement somewhere that generating UI automatically from DB layout (or business objects, or whatever other business layer) is a bad idea. I can also imagine a few good challenges that one would have to face in order to make something like this.
However I have not seen (nor could find) any examples of people attempting it. Thus I'm wondering - is it really that bad? It's definately not easy, but can it be done with any measure success? What are the major obstacles? It would be great to see some examples of successes and failures.
To clarify - with "generating UI automatically" I mean that the all forms with all their controls are generated completely automatically (at runtime or compile time), based perhaps on some hints in metadata on how the data should be represented. This is in contrast to designing forms by hand (as most people do).
Added: Found this somewhat related question
Added 2: OK, it seems that one way this can get pretty fair results is if enough presentation-related metadata is available. For this approach, how much would be "enough", and would it be any less work than designing the form manually? Does it also provide greater flexibility for future changes?
We had a project which would generate the database tables/stored proc as well as the UI from business classes. It was done in .NET and we used a lot of Custom Attributes on the classes and properties to make it behave how we wanted it to. It worked great though and if you manage to follow your design you can create customizations of your software really easily. We also did have a way of putting in "custom" user controls for some very exceptional cases.
All in all it worked out well for us. Unfortunately it is a sold banking product and there is no available source.
it's ok for something tiny where all you need is a utilitarian method to get the data in.
for anything resembling a real application though, it's a terrible idea. what makes for a good UI is the humanisation factor, the bits you tweak to ensure that this machine reacts well to a person's touch.
you just can't get that when your interface is generated mechanically.... well maybe with something approaching AI. :)
edit - to clarify: UI generated from code/db is fine as a starting point, it's just a rubbish end point.
hey this is not difficult to achieve at all and its not a bad idea at all. it all depends on your project needs. a lot of software products (mind you not projects but products) depend upon this model - so they dont have to rewrite their code / ui logic for different client needs. clients can customize their ui the way they want to using a designer form in the admin system
i have used xml for preserving meta data for this sort of stuff. some of the attributes which i saved for every field were:
friendlyname (label caption)
haspredefinedvalues (yes for drop
down list / multi check box list)
multiselect (if yes then check box
list, if no then drop down list)
datatype
maxlength
required
minvalue
maxvalue
regularexpression
enabled (to show or not to show)
sortkey (order on the web form)
regarding positioning - i did not care much and simply generate table tr td tags 1 below the other - however if you want to implement this as well, you can have 1 more attribute called CssClass where you can define ui specific properties (look and feel, positioning, etc) here
UPDATE: also note a lot of ecommerce products follow this kind of dynamic ui when you want to enter product information - as their clients can be selling everything under the sun from furniture to sex toys ;-) so instead of rewriting their code for every different industry they simply let their clients enter meta data for product attributes via an admin form :-)
i would also recommend you to look at Entity-attribute-value model - it has its own pros and cons but i feel it can be used quite well with your requirements.
In my Opinion there some things you should think about:
Does the customer need a function to customize his UI?
Are there a lot of different attributes or elements?
Is the effort of creating such an "rendering engine" worth it?
Okay, i think that its pretty obvious why you should think about these. It really depends on your project if that kind of model makes sense...
If you want to create some a lot of forms that can be customized at runtime then this model could be pretty uselful. Also, if you need to do a lot of smaller tools and you use this as some kind of "engine" then this effort could be worth it because you can save a lot of time.
With that kind of "rendering engine" you could automatically add error reportings, check the values or add other things that are always build up with the same pattern. But if you have too many of this things, elements or attributes then the performance can go down rapidly.
Another things that becomes interesting in bigger projects is, that changes that have to occur in each form just have to be made in the engine, not in each form. This could save A LOT of time if there is a bug in the finished application.
In our company we use a similar model for an interface generator between cash-software (right now i cant remember the right word for it...) and our application, just that it doesnt create an UI, but an output file for one of the applications.
We use XML to define the structure and how the values need to be converted and so on..
I would say that in most cases the data is not suitable for UI generation. That's why you almost always put a a layer of logic in between to interpret the DB information to the user. Another thing is that when you generate the UI from DB you will end up displaying the inner workings of the system, something that you normally don't want to do.
But it depends on where the DB came from. If it was created to exactly reflect what the users goals of the system is. If the users mental model of what the application should help them with is stored in the DB. Then it might just work. But then you have to start at the users end. If not I suggest you don't go that way.
Can you look on your problem from application architecture perspective? I see you as another database terrorist – trying to solve all by writing stored procedures. Why having UI at all? Try do it in DB script. In effect of such approach – on what composite system you will end up? When system serves different businesses – try modularization, selectively discovered components, restrict sharing references. UI shall be replaceable, independent from business layer. When storing so much data in DB – there is hard dependency of UI – system becomes monolith. How you implement MVVM pattern in scenario when UI is generated? Designers like Blend are containing lots of features, which cannot be replaced by most futuristic UI generator – unless – your development platform is Notepad only.
There is a hybrid approach where forms and all are described in a database to ensure consistency server side, which is then compiled to ensure efficiency client side on deploy.
A real-life example is the enterprise software MS Dynamics AX.
It has a 'Data' database and a 'Model' database.
The 'Model' stores forms, classes, jobs and every artefact the application needs to run.
Deploying the new software structure used to be to dump the model database and initiate a CIL compile (CIL for common intermediate language, something used by Microsoft in .net)
This way is suitable for enterprise-wide software and can handle large customizations. But keep in mind that this approach sets a framework that should be well understood by whoever gonna maintain and customize the application later.
I did this (in PHP / MySQL) to automatically generate sections of a CMS that I was building for a client. It worked OK my main problem was that the code that generates the forms became very opaque and difficult to understand therefore difficult to reuse and modify so I did not reuse it.
Note that the tables followed strict conventions such as naming, etc. which made it possible for the UI to expect particular columns and infer information about the naming of the columns and tables. There is a need for meta information to help the UI display the data.
Generally it can work however the thing is if your UI just mirrors the database then maybe there is lots of room to improve. A good UI should do much more than mirror a database, it should be built around human interaction patterns and preferences, not around the database structure.
So basically if you want to be cheap and do a quick-and-dirty interface which mirrors your DB then go for it. The main challenge would be to find good quality code that can do this or write it yourself.
From my perspective, it was always a problem to change edit forms when a very simple change was needed in a table structure.
I always had the feeling we have to spend too much time on rewriting the CRUD forms instead of developing the useful stuff, like processing / reporting / analyzing data, giving alerts for decisions etc...
For this reason, I made long time ago a code generator. So, it become easier to re-generate the forms with a simple restriction: to keep the CSS classes names. Simply like this!
UI was always based on a very "standard" code, controlled by a custom CSS.
Whenever I needed to change database structure, so update an edit form, I had to re-generate the code and redeploy.
One disadvantage I noticed was about the changes (customizations, improvements etc.) done on the previous generated code, which are lost when you re-generate it.
But anyway, the advantage of having a lot of work done by the code-generator was great!
I initially did it for the 2000s Microsoft ASP (Active Server Pages) & Microsoft SQL Server... so, when that technology was replaced by .NET, my code-generator become obsoleted.
I made something similar for PHP but I never finished it...
Anyway, from small experiments I found that generating code ON THE FLY can be way more helpful (and this approach does not exclude the SAVED generated code): no worries about changing database etc.
So, the next step was to create something that I am very proud to show here, and I think it is one nice resolution for the issue raised in this thread.
I would start with applicable use cases: https://data-seed.tech/usecases.php.
I worked to add details on how to use, but if something is still missing please let me know here!
You can change database structure, and with no line of code you can start edit data, and more like this, you have available an API for CRUD operations.
I am still a fan of the "code-generator" approach, and I think it is just a flavor of using XML/XSLT that I used for DATA-SEED. I plan to add code-generator functionalities.