设计模式
策略模式
定义
策略模式定义了算法簇,分别封装,让他们可以互相替换,次模式将算法独立于使用算法的客户
思想
- 多组合,少继承
- 针对接口编程,而不是针对实现编程
- 将变化代码,公用代码分离
- 核心思想是组合不同接口的实现,将接口定义到超类的变量中,通过构造函数或者方法来修改实现类,进而修改其行为。松耦合、可组合
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
思想
对用户透明