The Observer Design Pattern
Sample code and document are modified from last version in 2019
Executive Summary
In this lab exercise, you will gain experience in using the Observer design pattern, in this case in
the specific context of Java's implementation of the Observer design pattern in Swing.
To complete this assignment, you're going to need to refactor original code to meet our
requirements.
The Observer Pattern and Swing
The Observer pattern is often used in the development of Graphical User Interfaces (GUIs). When
a user of the interface interacts with some widget in the graphical representation of the
application, various objects within the application may need to be informed of the change so that
they can update the application's internal state. Swing introduces a new term for such clients:
listeners; applications associate (register) listeners with any GUI components the user may
interact with. Any component may have as many registered listeners as the application desires.
Game Rules:
Picture 1:
Picture 2:
Picture 3:
This is a pretty simple game with only three type of balls (red, blue and white).
Before starting the game, user can click ADD button to add red or blue balls. The initial score
of this game is 100. Score would minus 10 while adding a red ball, plus 30 while adding a blue
ball. All red and blue balls can be seen before the game starts. (Picture 1)
When click start button, the game starts while the white ball appears, at the same time all
three buttons in game frame can not be clicked anymore. (Picture 2)
Score will continuously decrease after the game starts. User could control balls through the
keyboard. Only ball that intersects with the white ball can be seen.
The rules of keyboard:
Balls Key to Action
White ball
a: xSpeed becomes -8
d: xSpeed becomes 8
w: ySpeed becomes -8
s: ySpeed becomes 8
Red ball
a: xSpeed becomes a negative random int
d: xSpeed becomes a positive random int
w: ySpeed becomes a negative random int
s: ySpeed becomes a positive random int
Blue ball All keys: change the direction of xSpeed, ySpeed respectively
If user click stop button, the game will terminate. Score will be calculated by the amount of
red and blue balls that white ball has caught. Score would plus 80 with each read ball and
minus 80 with each blue ball. (Picture 3)
Task 1 (40 points)
So this isn't terrible code, and it's actually quite common to see. But it's not at all a real
implementation of the observer pattern. The problem here is that the observed object is basically
observing itself and then dispatching its observations to the clients, instead of letting those clients
take care of their own observations.
First, let's create a new module named observer . Make a copy of the code you have in original
inside of the src folder in observer . Now let's think about the changes we want to make.
To be consistent with the Observer pattern, each of the interested components should register
itself to receive the keyboard’s events. The question is, who is really the "client" in this interaction?
If you answered " The Balls!" you would be exactly correct.
Hints
First, let's refactor our design. Provide a new class diagram depicting a design that allows each of
the interested observers to register themselves to receive the keyboard’s events.
There's a catch, though. I had to refactor the three type of balls into three different extensions of
the same abstract base class Ball (I called them RedBall , WhiteBall and BlueBall if you
want to follow my lead).
So, we can regard the MainPanel class as the implement class of Subject class, and regard
three type of Ball classes ( RedBall , WhiteBall and Blueball ) that extends the Ball as the
observer. So in the “Subject” class, you should design methods like registerObserver() ,
notifyObservers() , removeObserver() and measurementsChanged() (if you need). On the
whole, no matter how you design your project, you should guarantee that, when you press the
keyboard, it will notice the three ball classes and finally the xSpeed and ySpeed of three
type of ball classes would be changed accordingly.
To do
All right, now fix the code to observer pattern to decouple the complex code in public void
keyPressed(KeyEvent keyEvent) . Notice that do not change any rules of the game we have
declared.
Task 2 (60 points)
It actually is. It can be succinctly described by the fact that the WhiteBall doesn't have to know
anything about the existence of the BlueBall and RedBall at all! Fantastic.
Adding New Rules:
To make the game more interesting, adding news rules based on original rules:
When WhiteBall intersect with RedBall and BlueBall , keep changing its speed
RedBall : same as the speed of WhiteBall
BlueBall : change the direction of xSpeed and ySpeed
Hints and To do
According to the rules declared above, we know WhiteBall should notify its location to BlueBall
and RedBall when it moves, then the instance of BlueBall and the RedBall can update their
speed automatically when the WhiteBall is intersected with them.
Could you understand in shifting process, which class can be the subject and which class can be
observer? When to register observer and when to remove observer?
When notice white ball's location to BlueBall and RedBall.
Subject Interface Structure
What to check
Finish all tasks above. And:
Task 1 and 2 should to be implemented in the same module.
Each java file should not have any package declaration
For example, if I were to turn in my current files, my directory would unpack like the following:
Ball.java
BlueBall.java
RedBall.java
WhiteBall.java
Subject.java
ButtonPanel.java
MainPanel.java
MainFrame.java
Main.java
may be other java files (if you think is necessary)
public interface Subject<T> {
//when create a ball object, it is need to register the ball object into
observer list.
public void registerObserver(T t);
// when restart a new game, it is need to remove all observer from
paintinglist
public void removeObserver(T t);
// when clicked keyboard, it is need to notify all observers to update
their state
public void notifyObservers(char keyChar);
// For task 2: when white ball moved, it is need to notify all observers to
update their state
public void notifyObservers();
// or For task2 public void notifyObservers(int x, int y);
}
版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。