`

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

    博客分类:
  • Java
阅读更多
1、复合(Complex)模式部分

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

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

引用
Brain Power解答:
---------------------------------------------
适配器(Adapter)模式。
---------------------------------------------

呱呱叫解答:
---------------------------------------------
装饰者(Decorator)模式。
---------------------------------------------


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

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


*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);
	}

}
2
2
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics