创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
策略模式:定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
PS:即将对象的行为抽象出来成一个接口,用一组类来实现接口的行为,然后在对象类中使用接口来引用行为类。
Duck类
package headfirst.strategy;
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {
}
public void swim() {
System.out.println("Duck can swim!");
}
public void performQuack() {
quackBehavior.quack();
}
public void performFly() {
flyBehavior.fly();;
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
接口行为
package headfirst.strategy;
public interface QuackBehavior {
void quack();
}
package headfirst.strategy;
public interface FlyBehavior {
void fly();
}
接口行为实现
package headfirst.strategy;
public class FlyWithSwing implements FlyBehavior{
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("fly");
}
}
package headfirst.strategy;
public class Squack implements QuackBehavior{
@Override
public void quack() {
// TODO Auto-generated method stub
System.out.println("zhi zhi zhi");
}
}
package headfirst.strategy;
public class Quack implements QuackBehavior{
@Override
public void quack() {
// TODO Auto-generated method stub
System.out.println("gagaga");
}
}
实现的鸭子
package headfirst.strategy;
public class WhiteDuck extends Duck{
public WhiteDuck() {
flyBehavior = new FlyWithSwing();
quackBehavior = new Quack();
}
public static void main(String[] args) {
Duck model = new WhiteDuck();
model.performFly();
model.performQuack();
model.setQuackBehavior(new MuteQuack());
model.performQuack();
}
}
被观察对象 observer
松耦合 出版者 + 订阅者
观察者模式:定义了对象之间一对多依赖,这样一来,当一个对象状态改变时,他的所有依赖者都会收到通知并更新。
PS:出版者发生信息变化的时候会通知所有订阅者,订阅者和第三方类可以退订或者订购出版者的消息。
Subject接口 Observer接口
registerObserver(); update();
removeObserver(); 需要保存出版者的引用
notifyObserver(); 方便退订操作
实现类中有一个List
当信息改变时,循环调用所有Observer
的update();
java内置的 Observable 类 Observer接口
update(Observable obs,Object arg);
这里可以自定义用obs来get想要的数据
这里继承后可以设置
一个changd=false
当状态改变到一定时
设置true并调用update
接口 可以在Subject中设置一个flag 然后当数据变化到一定变化时再设置为true执行
package headfirst.observer;
public interface Observer {
void update(double temple,double dryrate);//推数据
void update(Subject subject,Object arg);//拉数据,可观察者自定义拉所需要的数据
}
package headfirst.observer;
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObserver();
}
实现类
package headfirst.observer;
import java.util.LinkedList;
import java.util.List;
/**
* Created by Alen on 2018/9/28.
*/
public class WeatherData implements Subject{
private double temple;
private double dryrate;
private List observers ;
WeatherData(){
observers = new LinkedList();
}
public double getTemple() {
return temple;
}
public double getDryrate() {
return dryrate;
}
public void measureChanged(){
notifyObserver();
}
public void setMeasure(double temple,double dryrate){
this.dryrate = dryrate;
this.temple = temple;
measureChanged();
}
@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 (Observer observer : observers) {
observer.update( temple, dryrate);
}
}
}
package headfirst.observer;
/**
* Created by Alen on 2018/9/28.
*/
public class Display implements Observer {
Subject subject;
private double temple;
private double dryrate;
Display( Subject subject){
this.subject=subject;
subject.registerObserver(this);
}
@Override
public void update(double temple,double dryrate) {
this.dryrate = dryrate;
this.temple = temple;
display();
}
public void display(){
System.out.println("this"+dryrate+","+temple);
}
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
Display display= new Display(weatherData);
weatherData.setMeasure(20,20);
}
}
利用Java Util包的实现
package headfirst.observer.useutil;
import java.util.Observable;
/**
* Created by Alen on 2018/9/28.
*/
public class WeatherData extends Observable{
private double temple;
private double dryrate;
WeatherData(){
}
public void measureChanged(){
setChanged();
notifyObservers();
}
public void setMeasure(double temple,double dryrate){
this.dryrate = dryrate;
this.temple = temple;
measureChanged();
}
public double getTemple() {
return temple;
}
public double getDryrate() {
return dryrate;
}
}
package headfirst.observer.useutil;
import java.util.Observable;
import java.util.Observer;
/**
* Created by Alen on 2018/9/28.
*/
public class Display implements Observer {
private double temple;
private double dryrate;
Observable observable;
Display(Observable observable){
this.observable = observable;
observable.addObserver(this);
}
@Override
public void update(Observable observable, Object arg) {
if (observable instanceof Observable){
WeatherData weatherData = (WeatherData) observable;
this.dryrate = weatherData.getDryrate();
this.temple = weatherData.getTemple();
display();
}
}
public void display(){
System.out.println("this"+dryrate+","+temple);
}
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
Display display = new Display(weatherData);
weatherData.setMeasure(1,1);
}
}
装饰者模式:动态地将责任附加到对象上,若需要扩展功能,装饰者提供了比继承更有弹性的替代方案
基础类
package headfirst.decorator;
//饮料类
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
咖啡类
package headfirst.decorator;
//浓咖啡
public class Espresso extends Beverage {
public Espresso(){
description = "Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
package headfirst.decorator;
//另外一种饮料
public class HouseBlend extends Beverage {
public HouseBlend(){
description = "HouseBlend";
}
@Override
public double cost() {
return 0.89;
}
}
装饰器类
package headfirst.decorator;
//调料装饰者
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();
}
package headfirst.decorator;
/**
* Created by Alen on 2018/9/28.
*/
public class Moka extends CondimentDecorator {
Beverage beverage ;
public Moka (Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",Moka";
}
@Override
public double cost() {
return 0.2+beverage.cost();
}
public static void main(String[] args) {
HouseBlend houseBlend = new HouseBlend();
Moka moka = new Moka(houseBlend);
System.out.println(moka.getDescription()+""+moka.cost());
Espresso espresso =new Espresso();
Moka moka1 = new Moka(espresso );
System.out.println(moka1.getDescription()+""+moka1.cost());
//double moka
Moka moka2 =new Moka(moka1);
System.out.println(moka2.getDescription()+""+moka2.cost());
}
}
简单工厂(Simple Factory)又叫做静态工厂方法(Static Factory Method) 有一个产品接口没有工厂接口
package com.wenniuwuren.simplefactory;
/**
* 工厂(Creator)角色 :简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。
* 工厂类可以被外界直接调用,创建所需的产品对象。
*
*/
public class SomethingCreator {
// 静态工厂 这就是为什么简单工厂又叫静态工厂方法
public static Tree factory(String fruitType) throws Exception{
if(fruitType.equals("Lemon")){
return new LemonTree();
}else if(fruitType.equals("Apple")){
return new AppleTree();
}else{
throw new Exception("暂时不支持生产该类型产品");
}
}
}
工厂方法模式:定义了一个创建对象的接口,但是由子类决定要实例化哪一个类,工厂方法把让类实例化推迟到子类。
抽象工厂模式:提供了一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例,也就是创建的是一个产品线下的多个产品。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
工厂方法创建 "一种" 产品,他的着重点在于"怎么创建",也就是说如果你开发,你的大量代码很可能围绕着这种产品的构造,初始化这些细节上面。也因为如此,类似的产品之间有很多可以复用的特征,所以会和模版方法相随。
抽象工厂需要创建一些列产品,着重点在于"创建哪些"产品上,也就是说,如果你开发,你的主要任务是划分不同差异的产品线,并且尽量保持每条产品线接口一致,从而可以从同一个抽象工厂继承。
单例模式:确保一个类只有一个实例,并且提供全局访问点
// 1.延迟初始化
private volatile Resource resource;
public Resource getResource() {
if (resource == null) {
synchronized (this) {
if (resource == null) {
resource = new Resource();
}
}
}
return resource;
}
// 2.快速初始化
public static Resource getResource() {//initialized 三个状态 ,其他检测到字段wei
return InstanceHolder.re; //第二个,就释放锁,挂起等待唤醒
}
private static class InstanceHolder {
public static Resource re = new Resource(); //会使用 Class对象初始化锁 和 state字段
} //其中状态有noInitialization initializing
// 3.同步初始化,性能差
public synchronized Resource getResource(){
if(null==resource){
resource = new Resource();
}
}
命令模式:将请求封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象。命令模式也支持可撤销的 操作。
PS:分隔开“发出请求的对象”与“接受和执行这些请求的对象”
服务员 Command
takeroder setCommand
orderup 客户端
厨师 execute
顾客 Receiver
package headfirst.command;
public interface Command {
public void execute();
public void undo();
}
package headfirst.command;
public class CommandController {
Command oncommand;
Command offcommand;
public void setCommand(Command oncommand,Command offcommand) {
this.offcommand = offcommand;
this.oncommand = oncommand;
}
public void onButtonWasPressed(){
oncommand.execute();
}
public void offButtonWasPressed(){
offcommand.execute();
}
}
package headfirst.command;
public class LigthOnCommand implements Command {
Light light;
LigthOnCommand(Light light){
this.light=light;
}
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
package headfirst.command;
public class Light {
void on() {
System.out.println("on");
}
void off() {
System.out.println("off");
}
}
public class test {
public static void main(String[] args) {
CommandController controller = new CommandController();
LigthOnCommand ligthOnCommand = new LigthOnCommand(new Light());
controller.setCommand(ligthOnCommand,ligthOnCommand);
controller.onButtonWasPressed();
}
}
适配器模式:将一个类的接口转换成客户期望的另外一个接口,适配器让原本接口不兼容的类可以合作无间
对象适配器:通过实现接口,然后使用 组合 关联。
类适配器:通过继承被适配对象,实现目标接口
// 对象适配器
// 适配器类,直接关联被适配类,同时实现标准接口
class Adapter implements Target{
// 直接关联被适配类
private Adaptee adaptee;
// 可以通过构造函数传入具体需要适配的被适配类对象
public Adapter (Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
// 这里是使用委托的方式完成特殊功能
this.adaptee.specificRequest();
}
}
// 测试类
public class Client {
public static void main(String[] args) {
// 使用普通功能类
Target concreteTarget = new ConcreteTarget();
concreteTarget.request();
// 使用特殊功能类,即适配类,
// 需要先创建一个被适配类的对象作为参数
Target adapter = new Adapter(new Adaptee());
adapter.request();
}
}
---------------------
类适配器
// 已存在的、具有特殊功能、但不符合我们既有的标准接口的类
class Adaptee {
public void specificRequest() {
System.out.println("被适配类 具有特殊功能...");
}
}
// 目标接口,或称为标准接口
interface Target {
public void request();
}
// 具体目标类,只提供普通功能
class ConcreteTarget implements Target {
public void request() {
System.out.println("普通类 具有普通功能...");
}
}
// 适配器类,继承了被适配类,同时实现标准接口
class Adapter extends Adaptee implements Target{
public void request() {
super.specificRequest();
}
}
// 测试类
public class Client {
public static void main(String[] args) {
// 使用普通功能类
Target concreteTarget = new ConcreteTarget();//实例化一个普通类
concreteTarget.request();
// 使用特殊功能类,即适配类
Target adapter = new Adapter();
adapter.request();
}
}
外观模式:提供了一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层接口,让子系统更容易使用
class HealthOffice implements Executive{
@Override
public void approve() {
System.out.println("卫生局通过审批");
}
}
class RevenueOffice implements Executive{
@Override
public void approve() {
System.out.println("税务局完成登记,定时回去收税");
}
}
class SaicOffice implements Executive{
@Override
public void approve() {
System.out.println("工商局完成审核,办法营业执照");
}
}
class ApproveFacade {
public ApproveFacade() {
}
public void wholeApprove() {
new HealthOffice().approve();
new RevenueOffice().approve();
new SaicOffice().approve();
}
}
public class FacadeTest {
public static void main(String[] args) {
System.out.println("开始办理行政手续...");
ApproveFacade af = new ApproveFacade();
af.wholeApprove();
System.out.println("行政手续终于办完了");
}
}
//避免了在main中
// new HealthOffice().approve();
// new RevenueOffice().approve();
// new SaicOffice().approve();
模版方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中来实现,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
public abstract CaffeineBeverage{
void prepare(){ //模版方法
boilWater();
brew();
pourInCup();
addCondiments();
hook(); //钩子,子类看情况要不要覆盖实现
}
void void boilWater(){
dosth("");
}
void pourInCup(){
dosth("");
}
abstract void brew();//由子类实现
abstract void addCondiments();//由子类实现
void hook(){
//do nothing!!!!
}
}
钩子:1.可以让子类实现算法中可选的部分
2.让子类对模版方法中即将发生的方法做出反应
迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示
组合模式Composite:允许你将对象组合成树形结构来表现“整体-部分”层次结构。组合能够让客户以一种
一致的方式处理个别对象以及对象组合
状态模式:允许对象内部状态改变的时候改变他的行为,对象看起来好像修改了它的类。
将状态变化委托到具体到状态类(实现state 接口)
对象内部有所有状态
包含一个(当前)state保存当前状态
调用当前对象类到request()方法来调用state.handle();
interface state{
CurrentClass class;//处理handle后改变状态使用
handle();
}
1.找出所有状态
2.创建一个实例持有目前的状态,然后给每个状态定义值
3.将系统中可以发生的动作整合
package headfirst.state;
public interface State {
void insertMoney();
void ejectMoney();
void trunCrank();
void dispensed();
}
package headfirst.state;
/**
* Created by Alen on 2018/10/5.
*/
public class SoldState implements State{
BookMachine bookMachine;
public SoldState(BookMachine bookMachine) {
this.bookMachine = bookMachine;
}
@Override
public void insertMoney() {
System.out.println("Please wait book out!");
}
@Override
public void ejectMoney() {
System.out.println("Sorry ,you have trun the Crank ");
}
@Override
public void trunCrank() {
System.out.println("should not trun again!!!!");
}
@Override
public void dispensed() {
bookMachine.releaseBook();
if(bookMachine.getCount()>0){
bookMachine.setState(bookMachine.getNoMoneyState());
}else {
System.out.println("book has sold out!!!!!");
bookMachine.setState(bookMachine.getSoldOutState());
}
}
}
package headfirst.state;
/**
* Created by Alen on 2018/10/5.
*/
public class WinnerState implements State {
BookMachine bookMachine;
public WinnerState(BookMachine bookMachine) {
this.bookMachine = bookMachine;
}
@Override
public void insertMoney() {
System.out.println("Please wait book out!");
}
@Override
public void ejectMoney() {
System.out.println("Sorry ,you have trun the Crank ");
}
@Override
public void trunCrank() {
System.out.println("should not trun again!!!!");
}
@Override
public void dispensed() {
System.out.println("you are winner,two book you get!");
bookMachine.releaseBook();
if(bookMachine.getCount()==0){
bookMachine.setState(bookMachine.getSoldOutState());
}else {
bookMachine.releaseBook();
if(bookMachine.getCount()>0){
bookMachine.setState(bookMachine.getNoMoneyState());
}else {
bookMachine.setState(bookMachine.getSoldOutState());
}
}
}
}
package headfirst.state;
/**
* Created by Alen on 2018/10/5.
*/
public class SoldOutState implements State{
BookMachine bookMachine;
public SoldOutState(BookMachine bookMachine) {
this.bookMachine = bookMachine;
}
@Override
public void dispensed() {
System.out.println("no dispensed");
}
@Override
public void trunCrank() {
System.out.println("sold out!!!!");
}
@Override
public void ejectMoney() {
System.out.println("return your money");
}
@Override
public void insertMoney() {
System.out.println("sold out!!!!please ejectMoney");
}
}
package headfirst.state;
/**
* Created by Alen on 2018/10/5.
*/
public class NoMoneyState implements State{
BookMachine bookMachine;
public NoMoneyState(BookMachine bookMachine) {
this.bookMachine = bookMachine;
}
@Override
public void insertMoney() {
System.out.println("you are insert money");
bookMachine.setState(bookMachine.getHasMoneyState());
}
@Override
public void ejectMoney() {
System.out.println("you are not insert money");
}
@Override
public void trunCrank() {
System.out.println("no money, insert money and try again!!!");
}
@Override
public void dispensed() {
System.out.println("you need pay first!!!!");
}
}
package headfirst.state;
import java.util.Random;
/**
* Created by Alen on 2018/10/5.
*/
public class HasMoneyState implements State {
BookMachine bookMachine;
Random randomWinner = new Random(System.currentTimeMillis());
public HasMoneyState(BookMachine bookMachine) {
this.bookMachine = bookMachine;
}
@Override
public void insertMoney() {
System.out.println("Had money!no need insert again!!!");
}
@Override
public void ejectMoney() {
System.out.println("return your money!!!");
bookMachine.setState(bookMachine.getNoMoneyState());
}
@Override
public void trunCrank() {
System.out.println("you turned....");
int winner = randomWinner.nextInt(10);
if ((winner == 0 )&& bookMachine.getCount() > 1) {
bookMachine.setState(bookMachine.getWinnerState());
} else {
bookMachine.setState(bookMachine.getSoldState());
}
}
@Override
public void dispensed() {
System.out.println("no gumball dispensed");
}
}
package headfirst.state;
/**
* Created by Alen on 2018/10/5.
*/
public class BookMachine {
State hasMoneyState;
State noMoneyState;
State soldOutState;
State soldState;
State winnerState;
int bookCount = 0;
State currentState;
public BookMachine(int count) {
this.bookCount = count;
hasMoneyState = new HasMoneyState(this);
noMoneyState = new NoMoneyState(this);
soldOutState = new SoldOutState(this);
soldState = new SoldState(this);
winnerState =new WinnerState(this);
if (count > 0) {
currentState = noMoneyState;
}
}
public void insertMoney() {
currentState.insertMoney();
}
public void ejectMoney() {
currentState.ejectMoney();
}
public void trunCrank() {
currentState.trunCrank();
currentState.dispensed();
}
void releaseBook() {
System.out.println("a gumball come rolling out the slot");
if (bookCount != 0) {
bookCount -= 1;
}
}
public int getCount() {
return bookCount;
}
public void setState(State state) {
currentState = state;
}
public State getState(){
return currentState;
}
public State getHasMoneyState() {
return hasMoneyState;
}
public State getWinnerState() {
return winnerState;
}
public State getNoMoneyState() {
return noMoneyState;
}
public State getSoldOutState() {
return soldOutState;
}
public State getSoldState() {
return soldState;
}
public State getCurrentState() {
return currentState;
}
}
public static void main(String[] args) {
BookMachine bookMachine = new BookMachine(10);
bookMachine.trunCrank();
System.out.println("==========================="+bookMachine.getCount());
bookMachine.insertMoney();
bookMachine.trunCrank();
System.out.println("==========================="+bookMachine.getCount());
bookMachine.insertMoney();
bookMachine.trunCrank();
}
代理模式:为另外一个对象提供一个替身或则占位符以控制对这个对象对访问
package headfirst.proxy;
public interface BuyHouse {
void buy();
}
package headfirst.proxy;
public class BuyHouseImp implements BuyHouse {
@Override
public void buy() {
System.out.println("buy");
}
}
1.静态代理
public class BuyHouseProxy implements BuyHouse {
private BuyHouse buyHouse;
public BuyHouseProxy(BuyHouse buyHouse) {
this.buyHouse = buyHouse;
}
@Override
public void buyHosue() {
System.out.println("买房前准备");
buyHouse.buyHosue();
System.out.println("买房后装修");
}
}
2.动态代理
package headfirst.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxyHandler implements InvocationHandler {
private Object object;
public DynamicProxyHandler(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object result = method.invoke(object, args);
System.out.println("after");
return result;
}
public static void main(String[] args) {
BuyHouse buyHouse = new BuyHouseImp();
BuyHouse buyHouseProxy = (BuyHouse)Proxy.newProxyInstance(BuyHouse.class.getClassLoader(),new Class[]{BuyHouse.class},new DynamicProxyHandler(buyHouse));
buyHouseProxy.buy();
}
}
3.CGLIB代理
package headfirst.proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGLibProxy implements MethodInterceptor {
private Object target;
public Object getInstance(Object target){
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("买房前准备");
Object result = methodProxy.invokeSuper(object, args);
// Object result = methodProxy.invoke(object, args);//error stack overflow!!!
System.out.println("买房后装修");
return result;
}
public static void main(String[] args) {
BuyHouse buyHouse = new BuyHouseImp();
CGLibProxy cglibProxy = new CGLibProxy();
BuyHouse buyHouseCglibProxy = (BuyHouse)cglibProxy.getInstance(buyHouse);
buyHouseCglibProxy.buy();
}
}
其中cglib代理与JDK中的代理比较:
JDK动态代理: 只能代理实现了接口的类 没有实现接口的类不能实现JDK动态代理。
Cglib代理: 针对类来实现代理,对指定目标 产生一个子类 通过方法拦截技术拦截所有父类方法的调用。
CGLib不能对声明为final的方法进行代理