设计模式学习篇(1)

1.策略模式

先说一下策略模式的定义:策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
Head First设计模式中是这么介绍策略模式的,假设你现在想要设计一个模拟Duck的游戏,很显然你需要设计一个SuperDuck超类,然后不同种类的Duck都继承这个SuperDuck,每种鸭子都会叫,会游泳,所以这部分在SuperDuck实现,每种鸭子的外观不同,所以display()是抽象的,需要子类具体实现。
这里写图片描述
后来产品经理对游戏提出了一个新的要求,就是要让鸭子加上fly的功能,于是开发人员就在Duck超类中加上了fly()方法,现在问题来了,有的鸭子(比如橡皮鸭)是不会飞的,但是继承了超类Duck后强行给它加上了飞的功能,为了让橡皮鸭不会飞,只能用空方法把fly覆盖掉,同时又发现一个同样的问题,有的鸭子是不会叫的,只能用同样的方法覆盖掉。这样每次修改fly或者叫的功能,都需要找到具体的Duck类,然后依次修改,这样逻辑很混乱。
为了是设计的思路更清晰,我们把代码中变化的和不变的区分出来,swim是是不变的,写在Duck超类中,而fly()和quack()是变化的,把它们单独拿出来。并分别设计两个超级接口
这里写图片描述
其中每一个接口就表示一族算法,这样就可以在Duck超类中设置FlyBehavior和QuackBehavior两个属性,来控制鸭子的飞和叫的行为。
而且鸭子的飞和叫可以动态的控制,这就是策略模式。
*在程序开发中要多针对接口编程而不是针对实现编程
这里写图片描述

2.观察者模式

ok,每天一个设计模式,呃,不对,昨天好像没有看,以后要每天看一个设计模式,fighting!
先看一下观察者模式的标准定义:观察者模式定义了对象之间一对多的依赖,这样一来,当一个对象状态改变的时候,它的所有依赖都会收到通知并自动更新。
也可以通过订阅报纸的例子来理解观察者模式:
这里写图片描述
在这里报社可以看作1,订阅者可以看作多。
还是从需求开始说,假设现在要求你编写一个模拟气象观测站的程序,这个观测站有一个WeatherData对象,它负责追踪气象变化,现在产品经理需要有一个应用,这个应用要有3个布告板,分别显示目前的天气状况,气象统计和简单的预报,它们的数据来自WeatherData对象,并且当WeatherData对象的状态改变的时候,3个布告板要实时更新。
下图可以清晰的看到我们需要做哪些任务:
这里写图片描述

这里写图片描述
在这个程序中,3个布告板对WeatherData就形成多对1的依赖关系,可以使用观察者模式。下面是用观察者模式进行的类图设计:
这里写图片描述
被观察者要实现Subject接口,而观察者要实现observer接口和Displayment接口,后者只是因为布告板都有display方法。

接口

public interface Subject {
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObserver();
}
public interface Observer {
    public void update(float temp,float humi,float press);
}
public interface Displayment {
    public void display();
}

WeatherData类


public class WeatherData implements Subject{
    private ArrayList<Observer> observers;
    private float temp,humi,press;

    public WeatherData() {
        observers = new ArrayList<Observer>();
    }
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);

    }

    @Override
    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        if(i>0)
            observers.remove(i);

    }

    @Override
    public void notifyObserver() {
        for(int i=0;i<observers.size();i++){
            observers.get(i).update(temp, humi, press);
        }

    }
    public void measurementChanged(){
        notifyObserver();
    }
    public void setMeasurements(float temp,float humi,float press){
        this.temp = temp;
        this.humi = humi;
        this.press = press;
        measurementChanged();
    }   
}

布告板类

class CurrentCoditionDisplay implements Observer,Displayment{
    private Subject weatherData;
    private float temp,humi,press;
    public CurrentCoditionDisplay(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }
    @Override
    public void display() {
        System.out.println("CurrentCoditionDisplay!!!!!");
        System.out.println(toString());
    }

    @Override
    public void update(float temp, float humi, float press) {
        this.temp = temp;
        this.humi = humi;
        this.press = press;
        display();
    }

    @Override
    public String toString() {
        return "CurrentCoditionDisplay [temp=" + temp + ", humi=" + humi + ", press=" + press + "]";
    }   
}
class StatisticDisplay implements Observer,Displayment{
    private Subject weatherData;
    private float temp,humi,press;
    public StatisticDisplay(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }
    @Override
    public void display() {
        System.out.println("StatisticDisplay!!!!!");
        System.out.println(toString());
    }

    @Override
    public void update(float temp, float humi, float press) {
        this.temp = temp;
        this.humi = humi;
        this.press = press;
        display();  
    }
    @Override
    public String toString() {
        return "StatisticDisplay [temp=" + temp + ", humi=" + humi + ", press=" + press + "]";
    }
}
class ForecastDisplay implements Observer,Displayment{
    private Subject weatherData;
    private float temp,humi,press;
    public ForecastDisplay(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }
    @Override
    public void display() {
        System.out.println("ForecastDisplay!!!!!");
        System.out.println(toString());
    }
    @Override
    public void update(float temp, float humi, float press) {
        this.temp = temp;
        this.humi = humi;
        this.press = press;
        display();

    }
    @Override
    public String toString() {
        return "ForecastDisplay [temp=" + temp + ", humi=" + humi + ", press=" + press + "]";
    }   
}

上面我们是自己设计的主题和观察者接口,在java中这部分已经实现。
这里写图片描述
*注意java中Obserable是一个类而不是接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值