3)A digital clock consists of a screen to display the time and a dial for setting in turn the year, month, day, hour and minute. Twisting the dial to the left reduces by one the value being changed but twisting it to the right increases it by one. Pushing the dial alters which value is being adjusted. At first, it is the year but after the dial is pushed once, it is the month, then after the dial is pushed again, it is the day and so on. Imagine the clock is represented by a class with attributes year, month, day etc. The following is what the code for a method rotateDialLeft() might look like. public void rotateDialLeft() { if (mode == YEAR_MODE) { year--; } else if (mode == MONTH_MODE) { month--; } else if (mode == DAY_MODE) { day--; } else if (mode == HOUR_MODE) { hour--; } else if (mode == MINUTE_MODE) { minute--; } } The code for rotateDialRight() is similar. Apply the Open-Closed Principle to explain why the above code is unsatisfactory from the design viewpoint, considering the possibility of future change to the code, giving an example of such a change. 5)Give the code required for the classes introduced in question 3), focusing on the code for a method selectState() which changes the value that is being adjusted from years to months. Make it clear in which classes the code is to be found. Assume the existence of other methods that are needed such as getMonthSetUpState(). 8)Suppose that in a multiplayer role-playing game, a class Client has a dependency to an interface Fighter with public methods attack(), defend() and escape(). The game designer now wishes for Client to use a class Wizard with three different but equivalent public methods castDestructionSpell(), shield() and portal(). Explain how it is possible to do this using an appropriate design pattern.
时间: 2024-02-14 21:07:35 浏览: 87
Negative refraction and subwavelength imaging of a photonic-crystal slab for the frequencies in the third band
3) The current implementation of the rotateDialLeft() method violates the Open-Closed Principle, which states that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. This means that we should be able to add new functionality without changing the existing code. In the current code, if we want to add a new mode (e.g. seconds), we would need to modify the existing if-else statements and add a new condition. This violates the Open-Closed Principle.
An example of a future change that could require modification of the existing code is if we wanted to add a new mode (e.g. century), we would need to modify the existing code and add a new condition. To fix this, we can use the Strategy pattern to encapsulate the different modes and their behavior and make the code more extensible.
5) Here is the code for the classes introduced in question 3:
```
public interface DialMode {
void rotateLeft();
void rotateRight();
void selectState();
}
public class YearMode implements DialMode {
private int year;
public YearMode(int year) {
this.year = year;
}
public void rotateLeft() {
year--;
}
public void rotateRight() {
year++;
}
public void selectState() {
// do nothing, already in year mode
}
}
public class MonthMode implements DialMode {
private int month;
public MonthMode(int month) {
this.month = month;
}
public void rotateLeft() {
month--;
}
public void rotateRight() {
month++;
}
public void selectState() {
// switch to day mode
int daysInMonth = getDaysInMonth();
DayMode dayMode = new DayMode(daysInMonth);
mode = dayMode;
}
private int getDaysInMonth() {
// implementation omitted
}
}
public class DayMode implements DialMode {
private int day;
public DayMode(int day) {
this.day = day;
}
public void rotateLeft() {
day--;
}
public void rotateRight() {
day++;
}
public void selectState() {
// switch to hour mode
HourMode hourMode = new HourMode(0);
mode = hourMode;
}
}
public class HourMode implements DialMode {
private int hour;
public HourMode(int hour) {
this.hour = hour;
}
public void rotateLeft() {
hour--;
}
public void rotateRight() {
hour++;
}
public void selectState() {
// switch to minute mode
MinuteMode minuteMode = new MinuteMode(0);
mode = minuteMode;
}
}
public class MinuteMode implements DialMode {
private int minute;
public MinuteMode(int minute) {
this.minute = minute;
}
public void rotateLeft() {
minute--;
}
public void rotateRight() {
minute++;
}
public void selectState() {
// switch to year mode
YearMode yearMode = new YearMode(2000);
mode = yearMode;
}
}
public class Clock {
private DialMode mode;
public Clock() {
YearMode yearMode = new YearMode(2000);
mode = yearMode;
}
public void rotateDialLeft() {
mode.rotateLeft();
}
public void rotateDialRight() {
mode.rotateRight();
}
public void selectState() {
mode.selectState();
}
}
```
The selectState() method is found in each DialMode implementation. In the MonthMode implementation, it switches to the DayMode, in the DayMode implementation, it switches to the HourMode, in the HourMode implementation, it switches to the MinuteMode, and in the MinuteMode implementation, it switches back to the YearMode.
8) We can use the Adapter pattern to adapt the interface of the Wizard class to the Fighter interface. First, we create an adapter class that implements the Fighter interface and has a reference to a Wizard object:
```
public class WizardAdapter implements Fighter {
private Wizard wizard;
public WizardAdapter(Wizard wizard) {
this.wizard = wizard;
}
public void attack() {
wizard.castDestructionSpell();
}
public void defend() {
wizard.shield();
}
public void escape() {
wizard.portal();
}
}
```
Now, we can use an instance of the WizardAdapter class wherever we need a Fighter object:
```
Client client = new Client();
Wizard wizard = new Wizard();
Fighter wizardAdapter = new WizardAdapter(wizard);
client.setFighter(wizardAdapter);
```
In this example, the Client class has a dependency on the Fighter interface. We create a Wizard object and wrap it in a WizardAdapter object that implements the Fighter interface. We then set the wizardAdapter as the fighter for the client. When the client calls the attack(), defend(), or escape() method, it will actually call the corresponding method on the Wizard object through the adapter. This allows us to use the Wizard class as if it implements the Fighter interface, without changing the interface of the Fighter or the implementation of the Wizard.
阅读全文