2006 Exam answers
m |
m (Reverted edits by Ebybymic (Talk); changed back to last version by Aidan Bebbington) |
||
(11 intermediate revisions by 5 users not shown) | |||
Line 5: | Line 5: | ||
# [1 mark] An approach for executing parse trees. | # [1 mark] An approach for executing parse trees. | ||
− | #: ''Answer:'' | + | #: ''Answer:'' [[Interpreter]] design pattern |
# [1 mark] It is better to use abstract classes than concrete ones. | # [1 mark] It is better to use abstract classes than concrete ones. | ||
− | #: ''Answer:'' | + | #: ''Answer:'' [[Program to the interface not the implementation]] |
# [1 mark] Design documentation is essential. | # [1 mark] Design documentation is essential. | ||
− | #: ''Answer:'' | + | #: ''Answer:'' [[Big design up front]] |
# [1 mark] A pattern containing a class called ''Quantity''. | # [1 mark] A pattern containing a class called ''Quantity''. | ||
− | #: ''Answer:'' | + | #: ''Answer:'' Measurement [[Analysis patterns|analysis pattern]] |
== Question 2 == | == Question 2 == | ||
Line 21: | Line 21: | ||
# [4 marks] Domain model objects should not access user interface objects. | # [4 marks] Domain model objects should not access user interface objects. | ||
− | #: ''Answer:'' | + | #: ''Answer:'' [[Presentation separation idiom]] or [[Interface should be dependent on model]] |
# [4 marks] A class should not access its subclasses. | # [4 marks] A class should not access its subclasses. | ||
− | #: ''Answer:'' | + | #: ''Answer:'' [[Dependency inversion principle]] |
# [4 marks] If a class is unlikely to change, it should be abstract. | # [4 marks] If a class is unlikely to change, it should be abstract. | ||
− | #: ''Answer:'' | + | #: ''Answer:'' [[Stable abstractions principle]] |
# [4 marks] Don’t initialise attributes in constructors; instead, initialise them the first time a getter is called. | # [4 marks] Don’t initialise attributes in constructors; instead, initialise them the first time a getter is called. | ||
− | #: ''Answer:'' | + | #: ''Answer:'' [[Use lazy initialization pattern]] |
− | # [4 marks] Structure code so that a ''foo()'' method in some object calls ''foo()''methods in other objects. | + | # [4 marks] Structure code so that a ''foo()'' method in some object calls ''foo()'' methods in other objects. |
− | #: ''Answer:'' | + | #: ''Answer:'' [[Recursion introduction]] |
# [4 marks] A maxim violated by the Observer pattern. | # [4 marks] A maxim violated by the Observer pattern. | ||
− | #: ''Answer:'' | + | #: ''Answer:'' [[Tell, don't ask]] or [[Don't burn your base class]] |
# [4 marks] Don’t write getters that return fields that can be changed. | # [4 marks] Don’t write getters that return fields that can be changed. | ||
− | #: ''Answer:'' | + | #: ''Answer:'' [[Don't expose mutable attributes]] or Riel's heuristic 9.2 (Do not change the state of an object without going through its public interface) |
== Question 3 == | == Question 3 == | ||
Line 45: | Line 45: | ||
[5 marks] Some designers suggest that it is a good idea to always declare separate interfaces from implementations, so that no class ever uses an implementation class directly; instead it uses only abstract interfaces. Is this a good idea? Justify your answer. | [5 marks] Some designers suggest that it is a good idea to always declare separate interfaces from implementations, so that no class ever uses an implementation class directly; instead it uses only abstract interfaces. Is this a good idea? Justify your answer. | ||
− | :''Answer:'' | + | :''Answer:'' Yes. See [[Program to the interface not the implementation]], [[Dependency inversion principle]], [[Stable abstractions principle]] |
+ | |||
+ | : I believe that this is a good idea for classes which are intended to be used between packages. Having a separate interface allows us to switch implementations very easily, even at run-time. However, for classes whose implementations are inextricably bound communication via interfaces would usually be redundant and would only obfuscate the relationships between these classes. Such classes should be in the same package (see [[Common closure principle]]). So I propose that classes in the same package should be allowed to communicate directly, but use interfaces where possible (ie. where there is stability, see [[Stable abstractions principle]]). For inter-package communication, interfaces should always be required. --[[User:Aidan Bebbington|Aidan]] 22:03, 14 October 2009 (UTC) | ||
== Question 5 == | == Question 5 == | ||
Line 56: | Line 58: | ||
:''Answer:'' | :''Answer:'' | ||
+ | |||
+ | * Ken Auer suggest always using getters and setters, even within the class a field is declared in ([[Implement behavior with abstract state pattern]]) | ||
+ | |||
+ | * Riel on the other hand suggests that we should be [[Beware of many accessors]]. He also tells developers to create a [[Minimal public interface]] and to [[Minimize number of methods]] which conflicts with Auer's suggestion of creating getters and setters for every field. His last heuristic, 9.2 (do not change the state of an object without going through its public interface), can be easily broken when using getters and setters by getting an object and changing it rather than going through the interface of the object containing that object. | ||
+ | |||
+ | * In both these papers the authors advise caution when using inheritance because inappropriate use of inheritance can reduce flexibility, maintainability and reusable. The difference is that Riel seems to have "given up" on inheritance to a greater degree. Auer advocates techniques for retaining flexibility while using inheritance, such as deferring the definition of a class's state until deeper in the hierarchy. Riel on the other hand advises us to [[Beware inheritance over composition]] and other things that suggest us to be cautious about inheritance, and carefully consider the alternatives. Auer also seems to believe that classes can themselves be reusable if they are well designed, whereas Riel believes in [[Reusable frameworks over reusable components]]. In general Auer seems to believe inheritance is the ultimate mechanism for reusability provided it is used well, whereas Riel seems to disagree saying that the framework is the more appropriate unit for software reuse, not the class. | ||
== Question 7 == | == Question 7 == |
Latest revision as of 03:10, 25 November 2010
Contents |
Question 1
[4 marks for whole question] Provide a name (and if possible a wiki or web page reference) for each idea (a)-(d):
- [1 mark] An approach for executing parse trees.
- Answer: Interpreter design pattern
- [1 mark] It is better to use abstract classes than concrete ones.
- [1 mark] Design documentation is essential.
- Answer: Big design up front
- [1 mark] A pattern containing a class called Quantity.
- Answer: Measurement analysis pattern
Question 2
[28 marks for whole question] For each of the following descriptions (a) – (g):
- [1 mark each] Name a maxim (or pattern, code smell, etc) that captures the idea.
- [1 mark each] Explain the rationale for this maxim (i.e. why the maxim exists).
- [2 marks each] Comment on the validity and value of this maxim.
- [4 marks] Domain model objects should not access user interface objects.
- [4 marks] A class should not access its subclasses.
- Answer: Dependency inversion principle
- [4 marks] If a class is unlikely to change, it should be abstract.
- Answer: Stable abstractions principle
- [4 marks] Don’t initialise attributes in constructors; instead, initialise them the first time a getter is called.
- Answer: Use lazy initialization pattern
- [4 marks] Structure code so that a foo() method in some object calls foo() methods in other objects.
- Answer: Recursion introduction
- [4 marks] A maxim violated by the Observer pattern.
- Answer: Tell, don't ask or Don't burn your base class
- [4 marks] Don’t write getters that return fields that can be changed.
- Answer: Don't expose mutable attributes or Riel's heuristic 9.2 (Do not change the state of an object without going through its public interface)
Question 3
[5 marks] If you could nominate one person to receive a lifetime achievement award for services to OO design, who would you choose, and why?
- Answer:
Question 4
[5 marks] Some designers suggest that it is a good idea to always declare separate interfaces from implementations, so that no class ever uses an implementation class directly; instead it uses only abstract interfaces. Is this a good idea? Justify your answer.
- Answer: Yes. See Program to the interface not the implementation, Dependency inversion principle, Stable abstractions principle
- I believe that this is a good idea for classes which are intended to be used between packages. Having a separate interface allows us to switch implementations very easily, even at run-time. However, for classes whose implementations are inextricably bound communication via interfaces would usually be redundant and would only obfuscate the relationships between these classes. Such classes should be in the same package (see Common closure principle). So I propose that classes in the same package should be allowed to communicate directly, but use interfaces where possible (ie. where there is stability, see Stable abstractions principle). For inter-package communication, interfaces should always be required. --Aidan 22:03, 14 October 2009 (UTC)
Question 5
[23 marks] See Frogs second design.
Question 6
[10 marks] What conflicts or differences of opinion can be detected between the ideas of ArthurRiel1996 and KenAuer1995? Do the underlying philosophies of the authors differ? Justify your answers, and where possible, support them with evidence from the papers.
- Answer:
- Ken Auer suggest always using getters and setters, even within the class a field is declared in (Implement behavior with abstract state pattern)
- Riel on the other hand suggests that we should be Beware of many accessors. He also tells developers to create a Minimal public interface and to Minimize number of methods which conflicts with Auer's suggestion of creating getters and setters for every field. His last heuristic, 9.2 (do not change the state of an object without going through its public interface), can be easily broken when using getters and setters by getting an object and changing it rather than going through the interface of the object containing that object.
- In both these papers the authors advise caution when using inheritance because inappropriate use of inheritance can reduce flexibility, maintainability and reusable. The difference is that Riel seems to have "given up" on inheritance to a greater degree. Auer advocates techniques for retaining flexibility while using inheritance, such as deferring the definition of a class's state until deeper in the hierarchy. Riel on the other hand advises us to Beware inheritance over composition and other things that suggest us to be cautious about inheritance, and carefully consider the alternatives. Auer also seems to believe that classes can themselves be reusable if they are well designed, whereas Riel believes in Reusable frameworks over reusable components. In general Auer seems to believe inheritance is the ultimate mechanism for reusability provided it is used well, whereas Riel seems to disagree saying that the framework is the more appropriate unit for software reuse, not the class.
Question 7
[25 marks] On your first day in a new software engineering job, you’re shown the Account class (Figure 3), which represents foreign exchange accounts that hold money in a particular currency. It records all exchanges of money from one Account to another, using the current exchange rate to calculate the result. Your manager says:
- "It is pretty much complete – it was designed by a top consultant – but we need you to extend it to cope with exchange rates that vary over time. We need to retain all info, so we should be able to find out what exchange rate was used for any exchange, even if it happened a long time ago. We also need it to handle more than 100 Accounts."
Criticise the design (and implementation) and suggest how it should be improved in order to support the requested features and to fix problems the manager was unaware of. Where possible, support your arguments and explain your design with maxims, patterns, refactorings, etc, and provide UML diagrams. If you need to make any assumptions about requirements, make a note of what you assumed and why.
public class Account { ... }
- Answer: