Why should I choose to use one instead of the other and in which cases?
I mainly focus on desktop applications and personally speaking I do find the humble dialog box more easy and natural to use.
In MVC, you would still use your "humble" dialog. Except all the business logic for it would be farmed off to another class somewhere else.
http://en.wikipedia.org/wiki/Model-view-controller
You need to weight up whether the investment in MVC will be worth it - especially if you're only working with a single simple dialog.
One of the best discussions I've found regarding the advantages and disadvantages of the model view controller/presenter patterns was written by Martin Fowler: http://martinfowler.com/eaaDev/uiArchs.html
In short, by choosing to use a MVC variant you are increasing the testability of your view (dialog). Keeping all of your logic in your dialog class on the other hand, can be fine if you do not expect that dialog to be very complex, however as the complexity increases, the benefit of testable code increases.
It really is a judgement call.
"Humble" dialogs themselves are already MVC. You have:
M, The content of the dialog's message.
V, The window and widgets the user can see.
C, How the dialog is displayed and how it responds to user activity.
Your GUI framework or wrapper library can provide MVC for you seamlessly without you having to think about it, but it's still MVC.
There is no simple answer.
You should use whatever will make your life easier.
If dialog is really simple, and you know for sure it is going to stay that way, go with humble dialog.
If you have something more complex, like multiple view presentations of the same data, or you know your simple dialog will become more complex over time, then, by all means, use MVC.
You can also take a look ant MVP pattern as an alternative to MVC.
Related
I'm trying to design a desktop UI for schematics, layout, drawing stuff. Just looking for high level advice from actual software designers.
Assuming an in-memory "database", (clojure map of arbitrary depth for all user data, and possibly another one for application preferences, etc.), I'm examining how to do the model-view-controller thing on these, where the data may be rendered and modified by any one or more of:
A standalone text field that shows a single parameter, such as box width.
An "inspector" type of view that shows multiple parameters of a selected object, such as box width, height, color, checkboxes, etc.
A table/spreadsheet type of view that shows multiple parameters of multiple objects, potentially the whole database
A graphical rendering of the whole thing, such as both schematic and layout view.
Modifying any one of these should show up immediately in every other active view, both text and graphical, not after clicking "ok"... so no modal boxes allowed. If for some reason the table view, an inspector view, and a graphical rendering are all in view, dragging the corner of the box graphically should immediately show up in the text, etc.
The platform in question is JavaFX, but I'd like a clean separation between UI and everything else, so I want to avoid binding in the JFX sense, as that ties my design data very tightly to JFX Properties, increases the graininess of the model, and forces me to work outside the standard clojure functions for dealing with data, and/or deal heavily with the whole getValue/setValue world.
I'm still assuming at least some statefulness/mutability, and the use of built-in Clojure functionality such as the ability to add-watch on an atom/var/ref and let the runtime signal dependent functions.
Platform-specific interaction will rest tightly with the actual UI, such as reifying ActionListeners, and dealing with ObservableValues etc., and will attempt to minimize the reliance on things like JavaFX Property for actual application data. I'm not entertaining FRP for this.
I don't mind extending JFX interfaces or making up my own protocols to use application-specific defrecords, but I'd prefer for the application data to remain as straight Clojure data, unsullied by the platform.
The question is how to set this all up, with closest adherence to the immutable model. I see a few options:
Fine-grain: Each parameter value/primitive (ie Long, Double, Boolean, or String) is an atom, and each view which can modify the value "reaches in" as far as it needs to in the database to change the value. This could suck as there could potentially be thousands of individual values (for example points on a hand-drawn curve), and will require lots of (deref...) junk. I believe this is how JFX would want to do this, with giant arrays of Properties at the leaf nodes, etc., which feels bloated. With this approach it doesn't seem much better than just coding it up in Java/C++.
Medium-grain: Each object/record in the database is an atom of a Clojure map. The entire map is replaced when any one of its values changes. Fewer total atoms to deal with, and allows for example long arrays of straight-up numbers for various things. But this gets complicated when some objects in the database require more nesting than others.
Coarse-grain: There is just one atom: the database. Any time anything changes, the entire database is replaced, and every view needs to re-render its particular portion. This feels a bit like using a hammer to swat a fly, and a naive implementation would require everything to re-render all the time. But I still think this is the best trade off, as any primitive has a clear access path from the root node, whether it is accessed on a per-primitive level or per-record level.
I also need the ability for one data template to be instantiated many times. So for example if the user changes a symbol or shape which is used in multiple places, a single edit will apply everywhere. I believe this also requires some type of "pointer"-like behavior. I think I can store a atom to the model, then instantiate as needed, and it can work in any of the above grain models.
Any other approaches? Is trying to do a GUI editor-like tool in a functional language just stupid?
Thanks
I don't think is stupid to use a functional language to do a GUI editor-like tool. But I can't claim to have an answer to your question. Here are some links that might help you in your journey:
Stuart Sierra - Components Just Enough Structure
Chris Granger - Light Table: Explains how Light Table (source) is structured.
Chris Granger - The IDE as a Value: blog post related to the video above
Conal Elliott - Tangible Functional Programming: Using Functional Reactive Programming to create a composable UI, but his code is in Haskell.
Nathan Herzing & Chris Shea - Helping voters with Pedestal, Datomic, Om and core.async
David Nolen - Comparative Literate Programming: Shows all to use core.async to simplify UI programming in ClojureScript. The ideas here can be used in a desktop UI.
Rich Hickey - The Language of the System: Amazing talk about system programming by the creator of Clojure.
Erik Meijer has a good quote about functional vs imperative code:
...no matter whether it's Haskell, C# Java, F#, Scala, Python, PHP think about the idea of having a sea of imperative code that interacts with the outside world and in there have islands of pure code where you write your functions in a pure way.
But you have to decide how big the islands are and how big the sea is. But the answer is never that there are only islands or only sea. A good programmer knows exactly the right balance.
I'm creating one tab based C++ application using GTK+ toolkit and Webkit for learning purpose. I've created following files
Main.cpp => Application entry-point
MainWindow.cpp/.h => MainWindow which creates toolbar object, Notebook, Statusbar
Toolbar.cpp/.h => toolbar items like back, forward, urlbar, stop/refresh,
NotebookContainer.cpp/.h => for creating new tab etc
TabWebView.cpp/.h => for creating tab(label+close button), web-view etc.
Now I want to communicate in between toolbar and TabView class. So when any event occur on toolbar I can do the action in webview.cpp and some event trigger from webview I can do the required on toolbar (like enabling/disabling stop button)
Which design pattern should I need to follow in this scenario?
NOTE: GTK+ is c based library.
I would like to suggest that you are asking the wrong question. Rather than asking what design pattern to follow, I would suggest you ask what the most idiomatic way to solve your problem is.
All too often the wors design failures I have to fix come from a young coder whose approach is "what design pattern can I use here?", or "How can I use more design patterns".
Studying design patterns is useful in providing a vocabulary for discussing your designs, and they are useful in inspiring and informing your design choices, but your design approach should always be "what the simplest, cleanest, most effective, idiomatic approach here". Sometimes the answer to that question will be a design pattern. Sometimes it will a part of a design pattern, and sometimes it will be something much simpler -- typically an idiom in the language or library you are working with.
I don't do a lot of GUI programming, so I can't help much with your concrete question. For the problem you are presenting, it sounds like you want to use GTK's signal/slot framework. Alternatively boost offers similar functionality if you want to get familiar with boost's tools. Both would be idiomatic approaches to what you want to do.
I think what you are looking for is some along the lines of an observer pattern:
http://sourcemaking.com/design_patterns/observer
and more generally something like Model-View-Controller or Presentation-Abstraction-Control models:
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
http://en.wikipedia.org/wiki/Presentation%E2%80%93abstraction%E2%80%93control
You might want to have a look at the Qt Signal/Slot implementation also:
http://qt-project.org/doc/qt-4.8/signalsandslots.html
I'm a testing noob and I need to test a JSF application. So I only just started exploring JSFUnit (read: I've googled it and StackOverflow-ed it), which as I understand uses/extends JUnit, HTMLUnit, HTTPUnit and other units that I have no idea about.
The thing is, the app uses Hibernate and what I want to know is whether or not I can use JSFUnit to create comprehensive tests that encompass model, view and controller, not to mention all that the HTTPUnit supposedly does?
Also, if I'm using Primefaces Dialog Framework so that my dialogs are not in the same page that opens said dialog, would I be able to test this approach? Or would it be better, in terms of testing, if my dialog was on the same page?
I hope my questions make sense. I promise they made sense in my head. Any help in this regard would be highly appreciated.
It seems that you require something more complex than pure unit tests.
Take a look at Selenium framework, as it simulates user interaction through a real recorded use case, and is easy to work with.
I want to develop a MFC application in VS2010. I hope to separate GUI from the logic, so that modifying GUI can become much easier. But I don't know how to design the classes to implement this function. Which design pattern should I use? Does MFC have any special way to deal with the problem?
Moreover, I am not familiar with design patterns. So I hope someone can give me samples or detailed articles explaining this. (Also I prefer a less complicated pattern! ^^)
Thank you very much!
The MFC already provide such a separation in their SDI/MDI based templates. For example, you have a CWinApp instance and a CMainFrame for the program itself. For each file in MDI apps you have a CDocument and a CView class.
Note:
The MFC don't use the classic MVC separation, they combine the view and controller into a single UI part.
The MFC are not strict about this, you can also put a button handler into the application/document, not only into the frame/view.
You don't fully separate the model from the MFC, it is still built on that. If you want to achieve this separation, you have to do additional work, but then you have a module that you can test completely separately. This allows you to use test-driven development, which is more difficult when embedded into a GUI.
May be it will be helpful http://martinfowler.com/eaaDev/uiArchs.html . Also try to find MVC (model/view/controller) pattern.
I tried to design the ui with some ui mocking software, but i found it's hard for me to settle down all the detail of the design, since the database didn't design yet.
But if i first design software, then the same problem occur, I didn't have the UI, how can I create a prominent UI ?
UI first.
Mock up an elegant and easy-to-use user interface (and workflow) thinking from the point of view of the user, and only then think about the underlying database / data structures you'll need to bring that UI to life.
If you can't design your UI because you haven't yet designed your database, you're doing it wrong IMHO. How many annoying pieces of software have you used that suffered from letting the database design drive the UI design?
Edit: As others have pointed out, you need to start with use cases / user stories. The UI design and database design, whichever order you do them, should only happen after you know what your software is trying to do, and for whom.
Edit by Bryan Oakley:
(source: gapingvoid.com)
Put the user at the place he deserves. Design UI first.
Database is only a consequence of user needs.
use cases first, neither ui nor database.
If you're trying to solve a problem in an object-oriented language, it's recommended that you start thinking about the objects involved. Don't worry about the database or the UI until you've got a solid domain model nailed down that addresses all the use cases.
You don't worry about the database or the UI at first. You can serialize objects to the file system if you need persistence and don't have a database. Being able to drive your app with a command line UI is a good exercise for guaranteeing that you have a good MVC separation.
Start with the objects.
UPDATE:
The one advantage that this approach has is that it doesn't prejudice the UI with a particular database design or vice versa. The object are agnostic about the other two layers. You aren't required to have a UI or relational database at all. You're just getting the objects right. Once you have that, you can create any UI or persistence scheme you like, confident that the domain model can handle the problem you've been asked to solve.
All the above answers address your issue in a right direction. That said, I would follow the SDLC thoroughly. It helps you understand the need for the solution for the problem at hand. Then comes the requirement gathering followed by the design either UI / underlying structure that supports the UI. It's a procedure but you would benefit in the end.
Your question is very subjective.
My opinion (and it is just that) is that database and underlying structure should come first. It can often help to put down the keyboard and mouse and compile some notes on paper.
Lay out goals like what you want your application to do, list the features you require and then start thinking about how you'll build it.
This method works for me in application design.
usually you need to manipulate some data in the solutions you develop. So you should consider how this data is organised first, stabilizing this layer is fundamental at the beginning. I agree with duffymo's comment about designing the business objects first if you are in a OO world. Mapping these objects to the DB will be a part of your work. Then you add business functionality and work on the presentation layer. Of course you will have to do some refactoring from time to time, but usually the refactoring impacts the business and presentation layers more than the database.
read this, it is a good technique.
DDD - Domain Driver Design
Would you build a house without a foundation? Database design isn't the fun part but it is the foundation of most business apps and if you get it wrong it becomes the most costly to fix and the most costly to maintain.
That said, I note that there is no reason you can't work on both together as they intertwine. But before you can do either, you need to understand the requirements and the business you are writing the app for.