**策略模式
策略模式: 定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
设计原则:
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
针对接口编程,而不是针对实现编程。
多用组合,少用继承
/**
* 描述:策略模式
* Created by zjw on 2018-12-24 20:31
*/
public class StrategyTest {
public static void main(String[] args) {
Character c = new King();
c.setWeapon(new AxeBehavior()).fight();
c.setWeapon(new BowAndArrowBehavior()).fight();
c.setWeapon(new KnifeBehavior()).fight();
c.setWeapon(new SwordBehavior()).fight();
Character c1 = new Queen();
c1.setWeapon(new AxeBehavior()).fight();
c1.setWeapon(new BowAndArrowBehavior()).fight();
}
// 武器行为接口
interface WeaponBehavior {
//怎么使用武器
void useWeapon();
}
static class AxeBehavior implements WeaponBehavior {
@Override
public void useWeapon() {
System.out.println("三板斧");
}
}
static class BowAndArrowBehavior implements WeaponBehavior {
@Override
public void useWeapon() {
System.out.println("弓箭射击");
}
}
static class KnifeBehavior implements WeaponBehavior {
@Override
public void useWeapon() {
System.out.println("匕首刺杀");
}
}
static class SwordBehavior implements WeaponBehavior {
@Override
public void useWeapon() {
System.out.println("剑斩");
}
}
// 角色抽象
static abstract class Character {
public WeaponBehavior weapon;
public abstract void fight();
public Character setWeapon(WeaponBehavior weapon) {
this.weapon = weapon;
return this;
}
}
static class King extends Character {
@Override
public void fight() {
System.out.print(this.getClass().getSimpleName()+ ":发动");
super.weapon.useWeapon();
}
}
static class Knight extends Character {
@Override
public void fight() {
System.out.print(this.getClass().getSimpleName()+ ":发动");
super.weapon.useWeapon();
}
}
static class Queen extends Character {
@Override
public void fight() {
System.out.print(this.getClass().getSimpleName()+ ":发动");
super.weapon.useWeapon();
}
}
static class Troll extends Character {
@Override
public void fight() {
System.out.print(this.getClass().getSimpleName()+ ":发动");
super.weapon.useWeapon();
}
}
}
**观察者模式:**定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖都会收到通知并自动更新。
设计原则:
为了交互对象之间的松耦合设计而努力
import java.util.ArrayList;
/**
* 描述:观察者模式
* Created by zjw on 2018-11-03 20:36
*/
public class ObserverTest {
public static void main(String[] args) throws InterruptedException {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay conditionsDisplay = new CurrentConditionsDisplay(weatherData);
StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
weatherData.setMeasurements(22,33,400);
Thread.sleep(3000);
weatherData.setMeasurements(20,35,420);
Thread.sleep(3000);
weatherData.setMeasurements(18,37,440);
}
//观察者模式-主题
interface Subject {
void registerObserver(Observer o );
void removeObserver(Observer o );
void notifyObserver();
}
//观察者模式-观察者
interface Observer {
void update(float temperature, float humidity, float pressure);
}
interface DisplayElement {
void display();
}
static class WeatherData implements Subject {
private ArrayList<Observer> observers;
private float temperature;//温度
private float humidity;//湿度
private float pressure;//压力
public WeatherData() {
observers = new ArrayList();
}
@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(o);
}
}
@Override
public void notifyObserver() {
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
public void measurementsChanged() {
notifyObserver();
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
}
static class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private float pressure;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println(String.format("通知部门已收到数据已变更,当前温度为%s 湿度为%s 压力为%s", temperature, humidity, pressure));
}
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
display();
}
}
static class ForecastDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private float pressure;
private Subject weatherData;
public ForecastDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println(String.format("预测部门已收到数据已变更,当前温度为%s 湿度为%s 压力为%s", temperature, humidity, pressure));
}
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
display();
}
}
static class StatisticsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private float pressure;
private Subject weatherData;
public StatisticsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override
public void display() {
System.out.println(String.format("统计部门已收到数据变更,当前温度为%s 湿度为%s 压力为%s", temperature, humidity, pressure));
}
@Override
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
display();
}
}
}
装饰者模式
**装饰者模式:**动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
设计原则:
类应该对扩展开放,对修改关闭
继承属于扩展形式之一,但不见得是达到弹性设计的最佳方式。
在我们的设计中,应该允许行为可以被扩展,而无须修改现有的代码。
组合和委托可用在运行时动态地加上新的行为。
除了继承,装饰者模式也可以让我们扩展行为。
装饰者模式意味着一群装饰者类,这些类用来包装具体组件。
装饰者类反映着出被装饰的组件类型(事实上,他们具有相同的类型,都经过接口或继承实现)。
装饰者可以在被装饰者的行为前面(与/或)后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的。
你可以用无数个装饰者包装一个组件。
装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。
装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。
package HeadFirstDesignMode.decorator;
/**
* 描述:
* Created by zjw on 2018-11-04 19:58
*/
public class StartBuckCoffee {
public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.cost());
Beverage beverage1 = new DarkRoast();
beverage1 = new Mocha(beverage1);
beverage1 = new Mocha(beverage1);
beverage1 = new Whip(beverage1);
System.out.println(beverage1.getDescription() + " $" + beverage1.cost());
Beverage beverage2 = new HouseBlend();
beverage2 = new Soy(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
}
// 饮料杯型、描述、成本
static abstract class Beverage {
// 小杯,中杯,大杯
public static int TALL = 1, GRANDE = 2, VENTI = 3;
public String description = "Unknown Beverage";
public int size = 0;
public String getDescription() {
return description;
}
public int getSize() {
return size;
}
//成本
public abstract double cost();
}
//装饰器
static abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
public abstract int getSize();
}
static class DarkRoast extends Beverage {
public DarkRoast() {
description = "Dark Roast";
}
@Override
public double cost() {
return 0.78;
}
}
static class Espresso extends Beverage {
public Espresso() {
description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
static class HouseBlend extends Beverage {
public HouseBlend() {
description = "House Blend Coffee";
}
@Override
public double cost() {
return 0.89;
}
}
static class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
@Override
public int getSize() {
return beverage.getSize();
}
@Override
public double cost() {
double cost = beverage.cost();
if (getSize() == Beverage.TALL) {
cost += 0.1;
} else if (getSize() == Beverage.GRANDE) {
cost += 0.15;
} else if (getSize() == Beverage.VENTI) {
cost += 0.20;
}
return cost;
}
}
static class Soy extends CondimentDecorator {
Beverage beverage;
public Soy(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Soy";
}
@Override
public int getSize() {
return beverage.getSize();
}
@Override
public double cost() {
return 0.55 + beverage.cost();
}
}
static class Whip extends CondimentDecorator {
Beverage beverage;
public Whip(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ",Whip";
}
@Override
public int getSize() {
return beverage.getSize();
}
@Override
public double cost() {
return 0.88 + beverage.cost();
}
}
}