《Head First设计模式》阅读笔记.第十二章

1、复合(Complex)模式部分

*模式通常被一起使用,并被组合在同一个设计解决方案中。

*复合模式在一个解决方案中结合两个或多个模式,以解决一般或重复发生的问题。

[quote]Brain Power解答:
---------------------------------------------
适配器(Adapter)模式。
---------------------------------------------

呱呱叫解答:
---------------------------------------------
装饰者(Decorator)模式。
---------------------------------------------[/quote]

Sharpen your pencil解答:
---------------------------------------------
public abstract class AbstractGooseFactory{
public abstract Quackable createGoose();
}

public class GooseFactory extends AbstractGooseFactory{
public Quackable createGoose(){
return new GooseAdapter(new Goose());
}
}
---------------------------------------------


Sharpen your pencil解答:
---------------------------------------------
public class QuackCounter implements Quackable,Observable{
Quackable duck;
static int numberOfQuacks;
Observable observable;

public QuackCounter(Quackable duck){
this.duck=duck;
observable=new Observable(this);
}

public void quack(){
duck.quack();
numberOfQuacks++;
}

public static int getQuacks(){
return numberOfQuacks;
}

public void registerObserver(Observer observer){
observable.registerObserver(observer);
}

public void notifyObservers(){
observable.notifyObservers();
}
}
---------------------------------------------


Sharpen your public解答:
---------------------------------------------
public class Flock implemtns Quackable,observable{
ArrayList quackers=new ArrayList();
Observable observable;

public Flock(){
observable=new Observable(this);
}

public void add(Quackable quacker){
quackers.add(quacker);
}

public void quack(){
Iterator it=quackers.iterator();
While(it.hasNext()){
Quackable quacker=(Quackable)it.next();
quacker.quack();
}
}

public void registerObserver(Observer observer){
Iterator it=quackers.iterator();
While(it.hasNext()){
Quackable quacker=(Quackable)it.next();
quacker.registerObserver(observer);
}
}

public void notifyObservers(){
}
}
---------------------------------------------


*使用组合(Compose)模式时,需要在安全性和透明性之间折中选择。

2、MVC模式部分(模型Model-视图View-控制器Controller)

*视图(View):用来呈现模型。视图通常直接从模型中取得它需要显示的数据和状态。

*控制器(Controller):取得用户的输入并解读其对模型的含义。

*模型(Model):模型持有所有的数据、状态和程序逻辑。模型没有注意到视图和控制器,虽然它提供了操纵和检索状态的接口,并发送状态改变通知给观察者。

*不把控制器的代码(解读视图的输入并操纵模型)放到模型中的原因有两个:
[quote]一、会让模型的代码更复杂。模型将具有两个责任,不但要管理用户界面,还要处理如何控制模型的逻辑。
二、会造成模型和视图之间的紧耦合,降低了可复用性。通过模型和视图之间的解耦,使设计更有弹性和容易扩展,能容纳改变。[/quote]

*MVC和JSP Model 2都属于复合模式。

3、复合(Complex)模式小结

*MVC是复合模式,结合了观察者模式、策略模式和组合模式。

*模型使用观察者模式,以便观察者更新,同时保持两者之间的解耦。

*控制器是视图的策略,视图可以使用不同的控制器实现,得到不同的行为。

*视图使用组合模式实现用户界面,用户界面通常组合了嵌套的组件,像面板、框架和按钮。

*这些模式写手合作,把MVC的三层解耦,这样可以保持设计干净又有弹性。

*在MVC模式中,适配器用来将新的模型适配成已有的模型和控制器。

*Model 2是MVC在Web上的应用。

*在Model 2,控制器实现成Servlet,而JSP/HTML实现视图。

4、MVC模式实例

/**
* 观察目标接口
*
* @author zangweiren 2010-4-12
*
*/
public interface Observable {
void notifyObservers();

void registerObserver(Observer observer);
}

/**
* 模型接口
*
* @author zangweiren 2010-4-12
*
*/
public interface Ball extends Observable {
int getSpeed();

void move();

void slowDown();

void speedUp();

void stop();
}

/**
* 模型实现类
*
* @author zangweiren 2010-4-12
*
*/
public class BallModel implements Ball {
private List<Observer> observers = new ArrayList<Observer>();
private int speed = 0;

@Override
public int getSpeed() {
return speed;
}

@Override
public void move() {
speed = 10;
this.notifyObservers();
}

@Override
public void notifyObservers() {
Iterator<Observer> it = observers.iterator();
while (it.hasNext()) {
Observer observer = it.next();
observer.speedChanged();
}
}

@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}

@Override
public void slowDown() {
if (speed > 0) {
speed -= 10;
this.notifyObservers();
}
}

@Override
public void speedUp() {
speed += 10;
this.notifyObservers();
}

@Override
public void stop() {
speed = 0;
this.notifyObservers();
}

}

/**
* 观察者接口
*
* @author zangweiren 2010-4-12
*
*/
public interface Observer {
void speedChanged();
}

/**
* 视图
*
* @author zangweiren 2010-4-12
*
*/
public class BallView implements Observer {
private BallController controller;
private Ball ballModel;

private JButton move;
private JButton stop;
private JButton speedUp;
private JButton slowDown;

private JFrame main = new JFrame();
private JPanel ballPanel;
private JButton ball;
private JLabel speed;

private boolean moving = false;

public BallView(BallController controller, Ball ballModel) {
this.controller = controller;
this.ballModel = ballModel;
this.ballModel.registerObserver(this);
initView();
showBall();
}

private void drawBall(int x, int y) {
ball.setLocation(x, y);
}

private void initView() {
main.setTitle("MVC Pattern");
main.setSize(300, 200);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setResizable(false);

move = new JButton("Move");
stop = new JButton("Stop");
speedUp = new JButton(">>");
slowDown = new JButton("<<");

ballPanel = new JPanel();
ball = new JButton();
ball.setBackground(Color.RED);
ball.setEnabled(false);
ball.setSize(20, 20);
ball.setLocation(0, 50);

JPanel p = new JPanel();
p.add(move);
p.add(slowDown);
p.add(speedUp);
p.add(stop);
stop.setEnabled(false);

speed = new JLabel("Current speed:" + ballModel.getSpeed());
JPanel speedPanel = new JPanel();

speedPanel.add(speed);
main.getContentPane().add(speedPanel, BorderLayout.NORTH);
ballPanel.add(ball);
main.getContentPane().add(ballPanel);
ballPanel.setLayout(null);
main.getContentPane().add(p, BorderLayout.SOUTH);
main.setVisible(true);

move.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
controller.move();
}
});
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
controller.stop();
}
});
speedUp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
controller.speedUp();
}
});
slowDown.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
controller.slowDown();
}
});
}

public void setMoveButtonEnable(boolean b) {
move.setEnabled(b);
}

public void setMoving(boolean b) {
this.moving = b;
}

public void setStopButtonEnable(boolean b) {
stop.setEnabled(b);
}

public void showBall() {
new Thread() {
@Override
public void run() {
int x = 0;
int y = 50;
while (true) {
if (!moving) {
continue;
}
drawBall(x, y);
try {
if (ballModel.getSpeed() != 0) {
Thread.sleep(1000 / ballModel.getSpeed());
x++;
if (x > 290) {
x = 0;
}
} else {
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}

@Override
public void speedChanged() {
speed.setText("Current speed:" + ballModel.getSpeed());
}
}

/**
* 控制器
*
* @author zangweiren 2010-4-12
*
*/
public class BallController {
private Ball ballModel;
private BallView view;

public BallController(Ball ballModel) {
this.ballModel = ballModel;
this.view = new BallView(this, ballModel);
}

public void move() {
ballModel.move();
view.setMoveButtonEnable(false);
view.setStopButtonEnable(true);
view.setMoving(true);
System.out.println("Ball is moving...");
}

public void slowDown() {
ballModel.slowDown();
System.out.println("Slow down:" + ballModel.getSpeed());
}

public void speedUp() {
ballModel.speedUp();
System.out.println("Speed up:" + ballModel.getSpeed());
}

public void stop() {
ballModel.stop();
view.setMoveButtonEnable(true);
view.setStopButtonEnable(false);
view.setMoving(false);
System.out.println("Ball is stopped.");
}
}

/**
* MVC测试类
*
* @author zangweiren 2010-4-12
*
*/
public class TestBallView {

public static void main(String[] args) {
Ball ballModel = new BallModel();
new BallController(ballModel);
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值