Description
We have a dojo about bounding-ball-base, the ball has two behavious, bouncing and Elastic.now we need to a new behavious about ball, bouncing-elastic. The first I finshed it by copying bouncing code and elastic code .It has too heavy code smell. Of course not to do so.
Question
- Why we do this dojo need strategy pattern ?
In Strategy pattern, we create objects which represent various strategies and a context object whose behavior varies as per its strategy object. The strategy object changes the executing algorithm of the context object. In this dojo, our ball needs three different behavios. so strategy pattern is best way to solve it.
- How many actor classes observer pattern uses ?
Context, Strategy, ConcreteStrategy. We are going to create a Strategy interface defining an action and concrete strategy classes implementing the Strategy interface. Context is a class which uses a Strategy.
- how to implemente it?
our demo class, will use Context and strategy objects to demonstrate change in Context behaviour based on strategy it deploys or uses.
Step1
Create an interface Behavior.java
public interface Behavior {
public int doOperation(int num1, int num2);
}
Step2
Bouncing.java
public class Bouncing implements Behavior {
@Override
public void action(Ball ball) {
direction = reverseDirectionIfNecessary(ball);
ball.y = move(ball);
}
}
Elastic.java
public class Elastic implements Behavior {
@Override
public void action(Ball ball) {
growthDirection = reverseGrowthDirectionIfNecessary(ball);
ball.radius = next(ball);
}
}
Step 3
Create Context Class.
Ball.java
public class Ball {
protected Ball(int x, int y, int radius, Collection behaviors) {
//TODO
}
protected Ball(int x, int y, Collection behaviors) {
this(x, y, DEFAULT_RADIUS, behaviors);
}
public void update() {
for (Behavior behavior : behaviors) {
behavior.action(this);
}
}
}
Step 4
Use the Context to see change in behaviour when it changes its Strategy.
BallFactory.java
package ball.model;
import java.util.ArrayList;
public class BallFactory {
public static Ball[] all() {
return new Ball[]{
bouncingBall(75, 50, Bouncing.DOWN),
bouncingElasticBall(450, 150, Bouncing.DOWN, Ball.DEFAULT_RADIUS, Elastic.SHRINK)
};
}
private static Ball bouncingElasticBall(int centerX, int centerY, int directionDown, int radius, int directionShrink) {
Behavior behaviorBouncing = new Bouncing(directionDown);
Behavior behaviorShrink = new Elastic(directionShrink);
ArrayList behaviorList = new ArrayList();
behaviorList.add(behaviorBouncing);
behaviorList.add(behaviorShrink);
return new Ball(centerX, centerY, radius, behaviorList);
}
public static Ball bouncingBall(int centerX, int centerY, int direction) {
Behavior behavior = new Bouncing(direction);
ArrayList behaviorList = new ArrayList();
behaviorList.add(behavior);
return new Ball(centerX, centerY, behaviorList);
}
}
- observer pattern applies?
- If there are many classes in a system, the difference between them is only their behavior, then use the policy model can dynamically let an object in a lot of behavior to choose a behavior.
- a system needs to dynamically select one of several algorithms.
- It is not desirable for the client to know the complex data structure associated with the algorithm, encapsulate the algorithm and the related data structure in the specific strategy class, and improve the confidentiality and security of the algorithm.
Thinking
if we not use Strategy Pattern,I think that these actions had to use multiple conditions to choose the statement to achieve.Of course, it's not a good idea. Although,the strategy pattern has help us solve the problem perfectly.But this is another question,The client must know all the policy classes and decide which policy class to use.