head first 设计模式笔记

/ java / 0 条评论 / 337浏览

设计模式

策略模式

定义

策略模式定义了算法簇,分别封装,让他们可以互相替换,次模式将算法独立于使用算法的客户

思想

  1. 多组合,少继承
  2. 针对接口编程,而不是针对实现编程
  3. 将变化代码,公用代码分离
  4. 核心思想是组合不同接口的实现,将接口定义到超类的变量中,通过构造函数或者方法来修改实现类,进而修改其行为。松耦合、可组合

public abstract class Duck {
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;

	public Duck() {
	}

	public void setFlyBehavior(FlyBehavior fb) {
		flyBehavior = fb;
	}

	public void setQuackBehavior(QuackBehavior qb) {
		quackBehavior = qb;
	}

	abstract void display();

	public void performFly() {
		flyBehavior.fly();
	}

	public void performQuack() {
		quackBehavior.quack();
	}

	public void swim() {
		System.out.println("All ducks float, even decoys!");
	}
}

观察者模式

定义

类似队列的广播模式,publish-->consumer,object-->observe,需观察者注册到主题,主题发生变化,通知观察者

思想

将观察者和主题松耦合,观察者改变不影响主题。可以有多个观察者,观察者可以自由订阅、取消。随着服务从一体集成到分布式。观察者模式很少使用,取而代之的是消息中间件。

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

装饰者模式

定义

思想

对扩展开放,对修改关闭,俗称开闭原则。通过继承来修改,不可以直接修改该类型。 通过扩展父类的方法,来实现装饰。如下LowCaseInputStream,通过重写父类read方法来实现装饰。装饰者模式有个小小的缺点,实现类会比较多,容易让人混乱,需要找到被装饰类。对理解帮助很大 装饰着模式

简单、抽象工厂模式

简单工厂:将对象的创建抽象出来,通过工厂统一管理对象的创建 抽象工厂:将对象的创建移动至实现抽象工厂的对象中

思想

面向接口编程,不依赖具体的实现,依赖倒置

public class SimplePizzaFactory {

	public Pizza createPizza(String type) {
		Pizza pizza = null;

		if (type.equals("cheese")) {
			pizza = new CheesePizza();
		} else if (type.equals("pepperoni")) {
			pizza = new PepperoniPizza();
		} else if (type.equals("clam")) {
			pizza = new ClamPizza();
		} else if (type.equals("veggie")) {
			pizza = new VeggiePizza();
		}
		return pizza;
	}
}

public interface PizzaAbstractFactory {
 
	public Dough createDough();
	public Sauce createSauce();
	public Cheese createCheese();
	public Veggies[] createVeggies();
	public Pepperoni createPepperoni();
	public Clams createClam();
 
}

单例模式

在一些场景全局只使用一个对象如:线程池、连接池、缓存 启动时加载:加载类是初始化对象,优点:简单 缺点:占用、浪费资源,有可能一致未使用,但是已加载 延迟加载(同步锁):getInstance 增加同步锁 优点:安全 缺点:性能差 延迟加载,双重锁校验(DCL):关键字voliate + sync 关键字

public class Singleton {
	private static Singleton uniqueInstance = new Singleton();
 
	private Singleton() {}
 
	public static Singleton getInstance() {
		return uniqueInstance;
	}
	
	// other useful methods here
	public String getDescription() {
		return "I'm a statically initialized Singleton!";
	}
}

public class Singleton {
	protected static Singleton uniqueInstance;
 
	// other useful instance variables here
 
	protected Singleton() {}
 
	public static synchronized Singleton getInstance() {
		if (uniqueInstance == null) {
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
	}
 
	// other useful methods here
}

public class Singleton {
	private volatile static Singleton uniqueInstance;
 
	private Singleton() {}
 
	public static Singleton getInstance() {
		if (uniqueInstance == null) {
			synchronized (Singleton.class) {
				if (uniqueInstance == null) {
					uniqueInstance = new Singleton();
				}
			}
		}
		return uniqueInstance;
	}
}

命令模式

将请求封装为对象,可以使用不同的请求、日志来参数化对象

适配器模式、外观模式

适配器模式

通过adapter 实现target,通过adapter调用adaptee(源角色)实现适配。 使用场景:新旧功能、系统之间相互兼容、适配 适配器模式

外观模式

将复杂操作封装一起,对外简介 使用场景:简化代码,对外保持简单

相似模式区别

模板方法

模板方法定义了一个或一组执行动作,由子类实现一个或多个步骤。 使用场景,抽象出一套骨架,具体业务实现骨架中的具体方法。采用继承抽象类方式。 对比策略模式:策略模式更注重组合的方式,相对灵活。模板方式更适用于规范

public abstract class CaffeineBeverageWithHook {
 
	final void prepareRecipe() {
		boilWater();
		brew();
		pourInCup();
		if (customerWantsCondiments()) {
			addCondiments();
		}
	}
 
	abstract void brew();
 
	abstract void addCondiments();
 
	void boilWater() {
		System.out.println("Boiling water");
	}
 
	void pourInCup() {
		System.out.println("Pouring into cup");
	}
 
	boolean customerWantsCondiments() {
		return true;
	}
}

迭代器

迭代器和模板有些类似,定义一个接口,实现接口中的方法,即可进行相关的next hasnext操作。 可以参考java 中的Iterator 接口 迭代器模式

组合模式

定义: 可以支持某种数据结构,通过类的组合,构造所需的数据结构,一个典型的场景是树形结构 定义一个组件MenuComponent(主节点)、菜单最小单元(叶子节点)、菜单(中间节点)

public abstract class MenuComponent {

    public void add(MenuComponent menuComponent) {
        throw new UnsupportedOperationException();
    }

    public void remove(MenuComponent menuComponent) {
        throw new UnsupportedOperationException();
    }

    public MenuComponent getChild(int i) {
        throw new UnsupportedOperationException();
    }

    public String getName() {
        throw new UnsupportedOperationException();
    }

    public String getDescription() {
        throw new UnsupportedOperationException();
    }

    public double getPrice() {
        throw new UnsupportedOperationException();
    }

    public boolean isVegetarian() {
        throw new UnsupportedOperationException();
    }

    public void print() {
        throw new UnsupportedOperationException();
    }
}


@Data
public class MenuItem extends MenuComponent {
	String name;
	String description;
	boolean vegetarian;
	double price;
	
	public void print() {
		System.out.print("  " + getName());
		if (isVegetarian()) {
			System.out.print("(v)");
		}
		System.out.println(", " + getPrice());
		System.out.println("     -- " + getDescription());
	}
}

public class Menu extends MenuComponent {
    ArrayList<MenuComponent> menuComponents = new ArrayList<MenuComponent>();
    String name;
    String description;
    
    public void add(MenuComponent menuComponent) {
        menuComponents.add(menuComponent);
    }

    public void remove(MenuComponent menuComponent) {
        menuComponents.remove(menuComponent);
    }

    public MenuComponent getChild(int i) {
        return (MenuComponent) menuComponents.get(i);
    }
    
    public void print() {
        System.out.print("\n" + getName());
        System.out.println(", " + getDescription());
        System.out.println("---------------------");

        Iterator<MenuComponent> iterator = menuComponents.iterator();
        while (iterator.hasNext()) {
            MenuComponent menuComponent = (MenuComponent) iterator.next();
            menuComponent.print();
        }
    }
}

组合模式关系

状态机模式

定义

状态(state) 事件(Event) 通过定义state实现状态基类的方法,从而实现该状态针对各个Event的处理并转变当前状态

思想

状态机模式,管理状态的流转,及该状态可执行的事件,解决了 if else 和 switch 判断较多问题 ,state -- >event--->state1 针对状态遵守了开闭原则,但是针对事件不适合。 状态机模式

代理模式

定义

为另一个对象提供一个替身或者占位符控制这个对象的访问,对用户透明。for example : rmi、dubbo、sping aop

思想

对用户透明