Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Imagine a small calculator GUI, with basic operations (+,-,/,*), and in the menu we can check for example scientific calculator and a small new view with the extra functions appears beside.

I was thinking that the decorator pattern is the solution but after reading some documentation on it, I am confused now. Which pattern would be more suitable for doing such things?

share|improve this question
    
composite pattern might work better than decorator –  tp1 Dec 26 '12 at 18:17
add comment

4 Answers

up vote 1 down vote accepted

I just took a look at the Windows XP calculator. While it's true that the number keys and the memory keys appear in the same general location in the standard and scientific view, I believe it is to create a consistent interface for the user.

Basically, a standard / scientific calculator presents two different views to the user. The scientific view is a super set of the standard view.

One way to write a calculator application is to write the code for the scientific view. A Strategy or Command pattern would prove useful in writing your calculator code.

You can then use the same code for the standard view, as the standard view is a subset of the scientific view.

Your application would switch views depending on the option the user selected.

share|improve this answer
add comment

You should really start writing the program/app before applying patterns. See what emerges instead of forcing some arbitrary pattern. Since it is a small calculator app you want to make, then there is really no need to apply a pattern just yet.

This is usually how I work; program something, then refactor towards a pattern if there is any need to. It is quite easy otherwise to over-engineer something.

In your case, you tried to apply the decorator pattern to handling views. In terms of data it might make sense, however views are completely different. Instead start to write one basic view to do the basic operations. Then try to create the scientific view, and refactor the code so that you can reuse the basic view's actions. You might end up with a M-V-C like structure.

share|improve this answer
2  
though I agree that force-fitting a pattern is a mistake, it is equally a mistake to "... start writing... before applying patterns." This may be useful for the OP because the application is trivial, but any non-trivial software development effort will require engineering practices including design and architecture, of which design patterns are integral. As general advice, -1 for the first statement. –  Steve Evers Dec 25 '12 at 20:34
    
@SnOrfus: I actually did advice MVC (which is a pattern) at the end of my answer. Though the question it is too vague to give any more concrete suggestions since the OP has not specified what language/dev.env. he/she is working in (for which I'd love to extend my answer if such was specified). Regardless of which, the scope still is so small that applying a specific pattern is rather pointless (in terms of context: a calculator is something college students are given as homework in 101 programming). –  Spoike Dec 25 '12 at 21:38
1  
-1 It's not an accident that they're called design patterns. Writing code first and then trying to evolve toward a standard solution to a common problem misses the point. –  Caleb Dec 25 '12 at 23:31
1  
@Caleb: Usually in my experience when using design patterns in the wrong way than what is intended starts with: "Hey, lets start by applying this pattern!" one week later "Why did we code it this way? It's just making things more difficult for us!" Evidently the OP already tried to apply a pattern ("Let's try decorator") before he ran into an actual problem (the question starts with "Imagine a XYZ program"). Don't get me wrong, I'm not saying that you shouldn't use patterns, but in this case why bother when there is no actual problem to apply it to? –  Spoike Dec 26 '12 at 0:36
2  
+1 @Caleb I agree with Spoike. By coding the problem, the developer gains intimate knowledge of the problem domain. At that point the developer can decide which, if any, pattern is appropriated. I have found that patterns organically materialize in code as the solution matures. –  Chuck Conway Dec 26 '12 at 16:55
show 2 more comments

I think you don't need a pattern in this case, but a principle. In this case, the Liskov Substitution Principle. Your small Views should implement the same Interface, so that the large View can manage them (to the extent that is needed based on the language you are using). The data Classes should also use this principle, so that the small View can be passed in data and return it to your wiring code without special consideration for what, specifically, is going on.

I find that I haven't been able to make an application of any complexity where Liskov Substitution is perfect, and that is possibly due to limitations in me vs. the principle. But I tend to think of it like a soda machine in a restaurant. You care about the specific type in the back room where you hook up the tubes to the boxes of syrup, and you care again when it's in your cup, but in between it all goes through the tube the same.

So I usually will have my endpoint Views type-check the IDataObject to make sure it's congruent with the View. The other end (the back room) for me is typically a Builder and/or an Abstract Factory that has references to many specific factories and calls on the correct ones based on some condition inherent in the data (I typically have a tag in the XML data source that says "pull the factory registered under this name" and a hash that contains the Factories).

I am fortunate to develop in Flash, and I allow Flash itself to be the Factory for my Views and simply pick up references to them once they've been instantiated, but if you have to manually construct Views, you can probably use something similar to what I've described for data construction.

I applaud that you're thinking through the design on the front in, because in real life few bosses will allow you to go back and rip out your initial experiments in favor of a more robust/maintainable design. Note that it is enough in the short-term to develop your Views and Model to Interfaces--you should find it much easier to add some kind of Factory later than it is to redo the logic that your management can physically see.

share|improve this answer
    
Amy, I think you have a fundamental misunderstanding regarding interfaces and the Liskov substitution principle. Most of the time, the consumer of an object who views it through an interface should never have to know what kind of implementation is underneath. That's why Liskov is so important -- if you violate Liskov, then the consumer had better find out which implementation he has so he can interact with it differently. The primary goal of interfaces is to hide the implementation. (I noticed a similar statement on another of your answers as well). –  Charlie Flowers Apr 27 '13 at 6:53
    
No, I understand it--that is why I said I have never been able to perfectly implement it. I use Liskov substitution to allow the implementors of the Interface to pass seamlessly through the wiring code, but at the endpoint it does become important what the particular implementation is. Like ordering from Amazon--Amazon cares what's in the box and I care what's in the box, but UPS doesn't. YMMV. –  Amy Blankenship Apr 27 '13 at 23:11
    
"It is impossible for a man to learn what he thinks he already knows." - Epictetus –  Charlie Flowers Apr 28 '13 at 16:35
    
Precisely... :) –  Amy Blankenship Apr 28 '13 at 18:20
add comment

Using MVC in conjunction with something like Prism would be a good choice in a scenario like this.

I'm not a big fan of using patterns, as it feels very restrictive if implemented from the start of a project , but it does create some sense of stability and promotes code re-use in a business if it's company policy.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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