HeadFirst 设计模式阅读笔记(一)—— strategy

最近正是圣诞假期,利用空闲时间翻翻《HeadFirst 设计模式》。这本书编的很有意思,读起来并不枯燥。所有设计模式的示例代码可以在官方网站免费下载:http://wickedlysmart.com/get-code/,但是我觉得自己写写可能更好些。


本系列笔记的目的不是把原书抄一遍,而是只摘录一些笔者认为重要的知识点,供以后查阅。希望详细学习的朋友们不妨去看看原书,确实比一般的技术书轻松多了。


第一章主要介绍了“策略模式”,以鸭子类为例讲述了这样一个问题:

  1. 最初设计鸭子这个基类时,我们定义了“呱呱叫”方法,子类“绿头鸭”继承鸭子类,一切显得很完美。
  2. 现在系统升级,多了很多种鸭子,比如“模型鸭子”,它真心不会叫,怎么办?
  3. 最简单的方法是在“模型鸭子”类中重写“呱呱叫”使之为空。但是很明显每次有新的不会叫的鸭子出现时我们都要想着重写这个方法,这显然是一个“肮脏”的解决方案。
  4. 于是我们想到可以把这个行为抽象成一个接口,每个子类根据自己的需要,如果能叫就实现这个接口。听上去不错。
  5. 可是别忘了,大部分鸭子还是呱呱叫的!使用接口使得我们不得不重复相同的代码。
  6. 如何在继承和复用之间找到平衡?
这是一些经验:
  • 为了复用而使用继承效果往往不完美
  • 针对接口而不是针对实现编程
  • 找出应用中可能变化的行为,把他们独立出来(封装)。如此一来系统变得更有弹性。
  • 多用组合少用继承
最终解决方案:
  1. 把“叫”这一方法抽象成为一个接口。
  2. 不同的叫的方式,比如呱呱叫和吱吱叫被抽象为具体的类,他们实现“叫”接口。
  3. 在基类“鸭子中”如此定义:
      
package headfirst.strategy;
public abstract class Duck {
FlyBehavior flyBehavior;
public Duck() {}
public void setQuackBehavior(QuackBehavior qb) {
quackBehavior = qb;
}
public void performQuack() {
quackBehavior.quack();
}
}
现在我们不再直接在类中实现“叫”方法(针对实现编程),而是定义了一个接口类型的属性来代表这一方法(针对接口编程),如此一来系统就变得灵活多了,因为子类的行为可以在运行时改变!
例:
ModelDuck.java,
public class ModelDuck extends Duck {
public ModelDuck() {
quackBehavior = new 呱呱叫();
}
main:
Duck model = new ModelDuck();
model.performQuack();//现在是呱呱叫
model.setQuackBehavior(new 吱吱叫());
model.performQuack();//现在是吱吱叫!


我们能够随时改变模型鸭子的叫声了。
这就是strategy模式:
定义一个算法族,分别封装起来让他们可以互相替换,此模式使算法的变化独立于使用算法的客户。
更直观的一个例子是,在射击游戏中,角色可以随时变化他们手中的枪!setWeapon()...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
观察者模式是一种常见的设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。在这个模式中,被观察者对象通常称为主题(Subject),而观察者对象通常称为观察者(Observer)。 下面我们就以一个简单的天气预报系统为例来介绍观察者模式的使用。 首先,我们需要定义一个主题接口(Subject),它包含了添加、删除和通知观察者的方法: ```java public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); } ``` 然后,我们需要定义一个观察者接口(Observer),它包含了更新数据的方法: ```java public interface Observer { public void update(float temp, float humidity, float pressure); } ``` 接下来,我们需要定义一个具体的主题类(WeatherData),它实现了主题接口,并包含了一个列表来存储观察者对象,以及当前的温度、湿度和气压等数据: ```java import java.util.ArrayList; public class WeatherData implements Subject { private ArrayList<Observer> observers; private float temperature; private float humidity; private float pressure; public WeatherData() { observers = new ArrayList<Observer>(); } public void registerObserver(Observer o) { observers.add(o); } public void removeObserver(Observer o) { int i = observers.indexOf(o); if (i >= 0) { observers.remove(i); } } public void notifyObservers() { for (int i = 0; i < observers.size(); i++) { Observer observer = (Observer)observers.get(i); observer.update(temperature, humidity, pressure); } } public void measurementsChanged() { notifyObservers(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } // other WeatherData methods here } ``` 最后,我们需要定义一个具体的观察者类(CurrentConditionsDisplay),它实现了观察者接口,并在更新数据时打印出当前的温度、湿度和气压等信息: ```java public class CurrentConditionsDisplay implements Observer { private float temperature; private float humidity; private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData) { this.weatherData = weatherData; weatherData.registerObserver(this); } public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; display(); } public void display() { System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity"); } } ``` 现在,我们可以创建一个天气预报系统,它包含了一个主题对象和一个观察者对象,并通过调用主题对象的方法来更新数据和通知观察者: ```java public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(78, 90, 29.2f); } } ``` 以上就是一个简单的观察者模式的例子,它可以让我们更好地理解和应用这个常见的设计模式

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值