zoukankan      html  css  js  c++  java
  • 《Head First 设计模式》学习笔记——观察者模式 + 装饰者模式

    装饰者模式是JDK中还有一个使用较多的设计模式,上一个是观察者模式(在Swing中大量使用),业内好的API设计无一离不开常见的设计模式,通常我们所说要阅读源代码,也是为了学习大牛们的设计思路。————题记

    设计模式
    观察者模式:定义了对象之间一对多的依赖,这样一来,当一个对象改变状态时。它的全部依赖者都会受到通知并自己主动更新。

    装饰者模式:动态地将责任附加到对象上。

    若要扩展功能。装饰者提供比继承者更有弹性的替代方案。


    设计原则
    (1)封装变化。

    (2)多用组合,少用继承。
    (3)针对接口编程,而不是针对实现编程。

    (4)为了交互对象之间的松耦合设计努力。

    对象之间的像话依赖降到了最低。有助于简历有弹性的OO系统,可以应对变化。
    (5)类应该对扩展开发。对改动关闭。

    目标是同意类easy扩展,在不改动现有代码的情况下,就能够搭配出新的行为。


    要点
    观察者模式定义了对象之间一对多的关系。

    使用观察者模式时。能够从被观察者出推或拉数据。
    观察者模式中。会改变的是主题的状态。以及观察者的数量和类型。用这个模式,你能够改变依赖于主题状态的对象,却不必改变主题。
    继承属于扩展形式之中的一个,但不见得是达到弹性设计的最佳方式。
    组合和托付可用于执行时动态加上新的行为。
    装饰者能够在被装饰者的行为前面与或后面加上自己的行为。甚至代替,达到特有的目的。
    装饰者会导致设计中出现很多小对象。假设过度使用。会让小程序变得复杂。

    Java内置的观察者模式:Obverser接口与Obversable类。

    缺点:
    (1)Obversable是一个类,必须设计一个类继承他。假设想同一时候具有Obversable类和还有一个超类的行为,就会陷入两难。由于Java不支持多重继承。Obversable没有接口,无法建立自己的实现。
    (2)Obversable将setChange()方法保护起来了。这样一来。除非继承,否则无法创建Obversable实例并组合到自己的对象中来。

    真实世界的装饰者
    java.io包内的类太多了。简直是排山倒海。

    以下是一个典型的对象集合,用装饰者来将功能结合起来。以读取文件数据:

    超类:InputStream
    组件:FileInputStream、StringBufferInputStream、ByteArrayInputStream
    抽象装饰者:FilterInputStream
    详细装饰者:PushBackInputStream、BufferedInputStream、DataInputStream、LineNumberInputStream

    观察者模式:
    public interface Subject {
    	public void registerObserver(Observer o);
    	public void removeObserver(Observer o);
    	public void notifyObservers();
    }
    
    public interface Observer {
    	public void update(float temp, float humidity, float pressure);
    }
    
    public interface DispalyElement {
    	public void dispaly();
    }
    
    public class WeatherData implements Subject {
    	private ArrayList observers;
    	private float temperature;
    	private float humidity;
    	private float pressure;
    	
    	public WeatherData() {
    		observers = new ArrayList();
    	}
    	
    	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();
    	}
    	
    	public float getTemperature() {
    		return temperature;
    	}
    	
    	public float getHumidity() {
    		return humidity;
    	}
    	
    	public float getPressure() {
    		return pressure;
    	}
    }
    
    //測试代码
    public class WeatherStation {
    	public static void main(String[] args) {
    		WeatherData weatherData = new WeatherData();
    		
    		CurrentConditionsDisplay currentDisplay =
    		new CurrentConditionsDisplay(weatherData);
    		
    		weatherData.setMeasurements(80,65,30.4f);
    	}
    }
    



    装饰者模式:
    //抽象类
    public abstract class Beverage {
    	String description = "Unknown Beverage";
      
    	public String getDescription() {
    		return description;
    	}
     
    	public abstract double cost();
    }
    
    //CondimentDecorator必须能代替Beverage。所以将CondimentDecorator必须能代替Beverage。所以将扩展成Beverage类扩展成Beverage类
    public abstract class CondimentDecorator extends Beverage {
    	//全部调料装饰者必须又一次实现getDescription()方法
    	public abstract String getDescription();
    }
    
    //饮料代码扩展自Beverage
    public class Espresso extends Beverage {
      
    	public Espresso() {
    		description = "Espresso";
    	}
      
    	public double cost() {
    		return 1.99;
    	}
    }
    
    //装饰者
    public class Soy extends CondimentDecorator {
    	Beverage beverage;//记录被装饰者
    
    	public Soy(Beverage beverage) {
    		this.beverage = beverage;
    	}
    
    	public String getDescription() {
    		return beverage.getDescription() + ", Soy";
    	}
    
    	public double cost() {
    		return .15 + beverage.cost();
    	}
    }
    
    //測试代码
    public class StarbuzzCoffee {
     
    	public static void main(String args[]) {
    		Beverage beverage = new Espresso();
    		System.out.println(beverage.getDescription() 
    				+ " $" + beverage.cost());
     
    		Beverage beverage2 = new DarkRoast();
    		beverage2 = new Mocha(beverage2);//层层装饰
    		beverage2 = new Mocha(beverage2);
    		beverage2 = new Whip(beverage2);
    		System.out.println(beverage2.getDescription() 
    				+ " $" + beverage2.cost());
     
    		Beverage beverage3 = new HouseBlend();
    		beverage3 = new Soy(beverage3);
    		beverage3 = new Mocha(beverage3);
    		beverage3 = new Whip(beverage3);
    		System.out.println(beverage3.getDescription() 
    				+ " $" + beverage3.cost());
    	}
    }



  • 相关阅读:
    C#利用反射动态调用类及方法
    系统程序监控软件
    SQL server 2008 安装和远程访问的问题
    sql server 创建临时表
    IIS 时间问题
    windows 2008 安装 sql server 2008
    sql server xml nodes 的使用
    Window 7sp1 安装vs2010 sp1 打开xaml文件崩溃
    CSS资源网址
    Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceModel, Version=3.0.0.0
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5306727.html
Copyright © 2011-2022 走看看