用来帮助我们创建对象
核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题。
关注对象之间的行为交互 .研究在系统运行时对象之间的相互通信和协作 ,进一步明确对象职责
注 : 划红线的只做了解 ,其他的重点掌握
package an.szxy.charinOfResponse;
/**
* 1.封装请假的基本信息
* @author chy
*
*/
public class LeaveRequest {
private String empName;
private int leaveDays;
private String reason;
public LeaveRequest(String empName, int leaveDays, String reason) {
super();
this.empName = empName;
this.leaveDays = leaveDays;
this.reason = reason;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public int getLeaveDays() {
return leaveDays;
}
public void setLeaveDays(int leaveDays) {
this.leaveDays = leaveDays;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}
package an.szxy.charinOfResponse;
/**
* 2. 抽象类
* @author chy
*
*/
public abstract class Leader {
protected String name;
protected Leader nextLeader; //责任链上的后继对象
public Leader(String name) {
super();
this.name = name;
}
//设定责任链上的后继对象
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
}
/**
* 处理请求的核心的业务方法
* @param request
*/
public abstract void handleRequest(LeaveRequest request);
}
package an.szxy.charinOfResponse;
/**
* 3. 主任
* @author Administrator
*
*/
public class Director extends Leader {
public Director(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getLeaveDays()<3){
System.out.println("员工:"+request.getEmpName()+"请假,天数:"+request.getLeaveDays()+",理由:"+request.getReason());
System.out.println("主任:"+this.name+",审批通过!");
}else{
if(this.nextLeader!=null){
this.nextLeader.handleRequest(request);
}
}
}
}
package an.szxy.charinOfResponse;
/**
* 4. 经理
* @author chy
*
*/
public class Manager extends Leader {
public Manager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getLeaveDays()<10){
System.out.println("员工:"+request.getEmpName()+"请假,天数:"+request.getLeaveDays()+",理由:"+request.getReason());
System.out.println("经理:"+this.name+",审批通过!");
}else{
if(this.nextLeader!=null){
this.nextLeader.handleRequest(request);
}
}
}
}
package an.szxy.charinOfResponse;
/**
* 5. 副总经理
* @author chy
*
*/
public class ViceGeneralManager extends Leader {
public ViceGeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getLeaveDays()<20){
System.out.println("员工:"+request.getEmpName()+"请假,天数:"+request.getLeaveDays()+",理由:"+request.getReason());
System.out.println("副总经理:"+this.name+",审批通过!");
}else{
if(this.nextLeader!=null){
this.nextLeader.handleRequest(request);
}
}
}
}
package an.szxy.charinOfResponse;
/**
* 测试责任链模式
* @author chy
*
*/
public class Client {
public static void main(String[] args) {
Leader a = new Director("张三");
Leader b = new Manager("李四");
Leader b2 = new ViceGeneralManager("李小四");
Leader c = new GeneralManager("王五");
//组织责任链对象的关系
a.setNextLeader(b);
b.setNextLeader(b2);
b2.setNextLeader(c);
//开始请假操作
LeaveRequest req1 = new LeaveRequest("TOM", 15, "回英国老家探亲!");
a.handleRequest(req1);
}
}
测试结果
uml类图
提供一种可以遍历聚合对象的方式。又称为:游标cursor模式
package ah.szxy.iterator;
/**
* 1. 自定义的迭代器接口
* @author chy
*
*/
public interface MyIterator {
void first(); //将游标指向第一个元素
void next(); //将游标指向下一个元素
boolean hasNext();//判断是否存在下一个元素
boolean isFirst();
boolean isLast();
Object getCurrentObj(); //获取当前游标指向的对象
}
package ah.szxy.iterator;
import java.util.ArrayList;
import java.util.List;
/**
*2. 自定义的聚合类
* @author Administrator
*
*/
public class ConcreteMyAggregate {
private List<Object> list = new ArrayList<Object>();
public void addObject(Object obj){
this.list.add(obj);
}
public void removeObject(Object obj){
this.list.remove(obj);
}
public List<Object> getList() {
return list;
}
public void setList(List<Object> list) {
this.list = list;
}
//获得迭代器
public MyIterator createIterator(){
return new ConcreteIterator();
}
//使用内部类定义迭代器,可以直接使用外部类的属性
private class ConcreteIterator implements MyIterator {
private int cursor; //定义游标用于记录遍历时的位置
@Override
public void first() {
cursor = 0;
}
@Override
public Object getCurrentObj() {
return list.get(cursor);
}
@Override
public boolean hasNext() {
if(cursor<list.size()){
return true;
}
return false;
}
@Override
public boolean isFirst() {
return cursor==0?true:false;
}
@Override
public boolean isLast() {
return cursor==(list.size()-1)?true:false;
}
@Override
public void next() {
if(cursor<list.size()){
cursor++;
}
}
}
}
package ah.szxy.iterator;
/**
* 测试迭代器模式
* @author chy
*
*/
public class Client {
public static void main(String[] args) {
ConcreteMyAggregate cma = new ConcreteMyAggregate();
cma.addObject("ah");
cma.addObject("szxy");
cma.addObject("chy");
MyIterator iter = cma.createIterator();
while(iter.hasNext()){
System.out.println(iter.getCurrentObj());
iter.next();
}
}
}
测试结果
如果一个系统之间对象的联系呈现为网状结构 ,对象之间存在大量多对多关系 ,导致关系及其复杂 ,这些对象成为同事关系 . 因此我们可以引入一个中介者对象 ,使各个同事对象只给中介者对象打交道 ,将复杂的关系化解为如下的星型结构
中介者模式的本质
解耦多个同事对象之间的关系 .每个对象都持有中介对象的引用 . 只要跟中介者对象打交道 ,我们可以通过中介者对象统一对这些关系进行管理
uml类图
package ah.szxy.mediator;
/**
*1. 同事类的接口
* @author chy
*
*/
public interface Department {
void selfAction(); //做本部门的事情
void outAction(); //向总经理发出申请
}
package ah.szxy.mediator;
/**
*2. 财务部
* @author chy
*
*/
public class Finacial implements Department {
private Mediator m; //持有中介者(总经理)的引用
public Finacial(Mediator m) {
super();
this.m = m;
m.register("finacial", this);
}
@Override
public void outAction() {
System.out.println("汇报工作!没钱了,钱太多了!怎么花?");
}
@Override
public void selfAction() {
System.out.println("数钱!");
}
}
package ah.szxy.mediator;
/**
* 3. 研发部
* @author chy
*
*/
public class Development implements Department {
private Mediator m; //持有中介者(总经理)的引用
public Development(Mediator m) {
super();
this.m = m;
m.register("development", this);
}
@Override
public void outAction() {
System.out.println("汇报工作!没钱了,需要资金支持!");
}
@Override
public void selfAction() {
System.out.println("专心科研,开发项目!");
}
}
package ah.szxy.mediator;
/**
* 3. 市场部
* @author chy
*
*/
public class Market implements Department {
private Mediator m; //持有中介者(总经理)的引用
public Market(Mediator m) {
super();
this.m = m;
m.register("market", this);
}
@Override
public void outAction() {
System.out.println("汇报工作!项目承接的进度,需要资金支持!");
m.command("finacial");
}
@Override
public void selfAction() {
System.out.println("跑去接项目!");
}
}
package ah.szxy.mediator;
/**
* 4. 中介者接口
* @author CHY
*
*/
public interface Mediator {
void register(String dname,Department d);
void command(String dname);
}
package ah.szxy.mediator;
import java.util.HashMap;
import java.util.Map;
/**
* 5. 总经理类 ,类似于中介者
* @author chy
*
*/
public class President implements Mediator {
private Map<String,Department> map = new HashMap<String , Department>();
@Override
public void command(String dname) {
map.get(dname).selfAction();
}
@Override
public void register(String dname, Department d) {
map.put(dname, d);
}
}
package ah.szxy.mediator;
/**
* 测试中介者模式
* @author chy
*
*/
public class Client {
public static void main(String[] args) {
Mediator m = new President();
Market market = new Market(m);
Development devp = new Development(m);
Finacial f = new Finacial(m);
market.selfAction();
market.outAction();
}
}
将一个请求封装成一个对象 ,从而使我们可用不同请求对客户进行参数化 :对请求排队或记录请求日志 ,以及支持可撤销的操作 .也叫: 动作Action模式 ,事务transaction 模式.
结构
uml类图
package ah.szxy.command;
/**
* 1. 声明命令接口以及具体命令
* @author chy
*
*/
public interface Command {
/**
* 这个方法是一个返回结果为空的方法。
* 实际项目中,可以根据需求设计多个不同的方法
*/
void execute();
}
class ConcreteCommand implements Command {
private Receiver receiver; //命令的真正的执行者
public ConcreteCommand(Receiver receiver) {
super();
this.receiver = receiver;
}
@Override
public void execute() {
//命令真正执行前或后,执行相关的处理!
receiver.action();
}
}
package ah.szxy.command;
/**
* 2. 调用者/发起者
* @author chy
*
*/
public class Invoke {
private Command command; //也可以通过容器List<Command>容纳很多命令对象,进行批处理。数据库底层的事务管理就是类似的结构!
public Invoke(Command command) {
super();
this.command = command;
}
//业务方法 ,用于调用命令类的方法
public void call(){
command.execute();
}
}
package ah.szxy.command;
/**
* 3 .真正的命令的执行者
* @author chy
*
*/
public class Receiver {
public void action(){
System.out.println("Receiver.action(收到命令)");
}
}
package ah.szxy.command;
/**
* 测试命令模式
* @author chy
*
*/
public class Client {
public static void main(String[] args) {
Command c = new ConcreteCommand(new Receiver());
Invoke i = new Invoke(c);
i.call();
new Receiver().action();
}
}
测试结果
对应于解决某个问题的一个算法族 ,允许用户从该算法族中选取任意一个算法解决某个问题 ,同时可以方便的更换算法或者增加新的算法 ,并且由客户端决定调用哪个算法
本质 分离算法 , 选择实现
代码原型
uml类图
package ah.szxy.strategy;
/**
* 不使用策略模式的代码
*
* 实现起来比较容易,符合一般开发人员的思路
* 假如,类型特别多,算法比较复杂时,整个条件语句的代码就变得很长,难于维护。
* 如果有新增类型,就需要频繁的修改此处的代码!
* 不符合开闭原则!
* @author chy
*
*/
public class TestStrategy {
public double getPrice(String type, double price) {
if (type.equals("普通客户小批量")) {
System.out.println("不打折,原价");
return price;
} else if (type.equals("普通客户大批量")) {
System.out.println("打九折");
return price * 0.9;
} else if (type.equals("老客户小批量")) {
System.out.println("打八五折");
return price * 0.85;
} else if (type.equals("老客户大批量")) {
System.out.println("打八折");
return price * 0.8;
}
return price;
}
}
package ah.szxy.strategy;
/**
* 1. 策略模式的接口类
* @author chy
*
*/
public interface Strategy {
public double getPrice(double standardPrice);
}
package ah.szxy.strategy;
/**
* 2. 策略模式实现类
* 新客户 少量购买
* @author chy
*
*/
public class NewCustomerFewStrategy implements Strategy {
@Override
public double getPrice(double standardPrice) {
System.out.println("不打折,原价");
return standardPrice;
}
}
package ah.szxy.strategy;
/**
*2. 策略模式实现类
* 新客户 大量购买
* @author chy
*
*/
public class NewCustomerManyStrategy implements Strategy {
@Override
public double getPrice(double standardPrice) {
System.out.println("打九折");
return standardPrice*0.9;
}
}
package ah.szxy.strategy;
/**
* 2. 策略模式实现类
* 老客户 少量购买
* @author chy
*
*/
public class OldCustomerFewStrategy implements Strategy {
@Override
public double getPrice(double standardPrice) {
System.out.println("打八五折");
return standardPrice*0.85;
}
}
package ah.szxy.strategy;
/**
* 2 .策略模式实现类
* 老客户 大量购买
* @author chy
*
*/
public class OldCustomerManyStrategy implements Strategy {
@Override
public double getPrice(double standardPrice) {
System.out.println("打八折");
return standardPrice*0.8;
}
}
package ah.szxy.strategy;
/**
*3. 负责和具体的策略类交互(核心代码)
* 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化。
* 如果使用spring的依赖注入功能,还可以通过配置文件,动态的注入不同策略对象,动态的切换不同的算法.
*
* @author chy
*
*/
public class Context {
private Strategy strategy; //当前采用的算法对象
//可以通过构造器来注入
public Context(Strategy strategy) {
super();
this.strategy = strategy;
}
//可以通过set方法来注入
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void pringPrice(double s){
System.out.println("您该报价:"+strategy.getPrice(s));
}
}
package ah.szxy.strategy;
/**
* 测试策略模式
* @author chy
*
*/
public class Client {
public static void main(String[] args) {
Strategy s1 = new OldCustomerManyStrategy();
Context ctx = new Context(s1);
ctx.pringPrice(1111);
}
}
测试结果
模板方法模式时编程中经常用到的模式. 他定义了一个操作中的算法骨架,加某些延迟延迟到子类中实现. 这样,新的子类可以在不改变一个算法结构的前提下重新定义该算法的某些特定场景
实质
代码原型
package templateMethod;
/**
* 定义模板的抽象方法
* @author chy
*
*/
public abstract class BankTemplateMethod {
//具体方法
public void takeNumber(){
System.out.println("取号排队");
}
public abstract void transact(); //办理具体的业务 //钩子方法
public void evaluate(){
System.out.println("反馈评分");
}
public final void process(){ //模板方法!!!
this.takeNumber();
this.transact();
this.evaluate();
}
}
package templateMethod;
/**
* 测试模板方法模式
* @author chy
*
*/
public class Client {
public static void main(String[] args) {
BankTemplateMethod btm = new DrawMoney();
btm.process();
System.out.println("-----------");
//采用匿名内部类
BankTemplateMethod btm2 = new BankTemplateMethod() {
@Override
public void transact() {
System.out.println("我要存钱!");
}
};
btm2.process();
System.out.println("-------------");
BankTemplateMethod btm3 = new BankTemplateMethod() {
@Override
public void transact() {
System.out.println("我要理财!我这里有2000万");
}
};
btm3.process();
}
}
class DrawMoney extends BankTemplateMethod {
@Override
public void transact() {
System.out.println("我要取款!!!");
}
}
测试结果
uml类图
package ah.szxy.state;
/**
* 1. 状态模式的接口
* @author chy
*
*/
public interface State {
void handle();
}
package ah.szxy.state;
/**
* 2. 空闲状态
* @author chy
*
*/
public class FreeState implements State {
@Override
public void handle() {
System.out.println("房间空闲!!!没人住!");
}
}
package ah.szxy.state;
/**
*2 . 已预订状态
* @author chy
*
*/
public class BookedState implements State {
@Override
public void handle() {
System.out.println("房间已预订!别人不能定!");
}
}
package ah.szxy.state;
/**
*2. 已入住状态
* @author chy
*
*/
public class CheckedInState implements State {
@Override
public void handle() {
System.out.println("房间已入住!请勿打扰!");
}
}
package ah.szxy.state;
/**
* 3. 房间对象(核心)
* 代表当前状态 以及状态之间切换的方法
*
* @author chy
*
*/
public class HomeContext {
//如果是银行系统,这个Context类就是账号。根据金额不同,切换不同的状态!
private State state;
public void setState(State s){
System.out.println("修改状态!");
state = s;
state.handle();
}
}
package ah.szxy.state;
/**
* 测试状态模式
* @author chy
*
*/
public class Client {
public static void main(String[] args) {
HomeContext ctx = new HomeContext();
ctx.setState(new FreeState());
ctx.setState(new BookedState());
ctx.setState(new FreeState());
}
}
测试结果
uml类图
package ah.szxy.observer;
/**
* 1. 观察者接口
*
* @author chy
*
*/
public interface Observe {
void update(Subject subject);
}
package ah.szxy.observer;
/**
* 2 .主题对象
* @author chy
*
*/
import java.util.ArrayList;
import java.util.List;
public class Subject {
protected List<Observe> list=new ArrayList<Observe>();
public void registerObserve(Observe objs) {
list.add(objs);
}
public void removeObserve(Observe objs) {
list.remove(objs);
}
/**
* 通知所有观察者更新状态
*/
public void notifyAllObserve() {
for (Observe objs : list) {
objs.update(this);
}
}
}
package ah.szxy.observer;
/**
* 3. 主体对象的子类
* @author chy
*
*/
public class ConcreteSubject extends Subject{
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
/**
* 主体对象发生变化 ,通知所有观察者
*/
this.notifyAllObserve();
}
}
package ah.szxy.observer;
/**
* 4. 观察者的实现类
* @author chy
*
*/
public class ObserverA implements Observe {
private int mystate;
@Override
public void update(Subject subject) {
mystate = ((ConcreteSubject)subject).getState();
}
public int getMystate() {
return mystate;
}
public void setMystate(int mystate) {
this.mystate = mystate;
}
}
package ah.szxy.observer;
public class Client {
public static void main(String[] args) {
//创建目标对象
ConcreteSubject subject = new ConcreteSubject();
//创建多个对象
ObserverA objs1=new ObserverA();
ObserverA objs2=new ObserverA();
ObserverA objs3=new ObserverA();
//将这三个观察者添加到subject的观察者队伍中
subject.registerObserve(objs1);
subject.registerObserve(objs2);
subject.registerObserve(objs3);
//修改subject的值
subject.setState(666);
//查看观察者的变化
System.out.println("----------------");
System.out.println(objs1.getMystate());
System.out.println(objs2.getMystate());
System.out.println(objs3.getMystate());
//修改subject的值
subject.setState(2333);
//查看观察者的变化
System.out.println("----------------");
System.out.println(objs1.getMystate());
System.out.println(objs2.getMystate());
System.out.println(objs3.getMystate());
}
}
测试结果
基于java自带的接口实现的观察者模式(java.util.Observable\ java.util.Observer)
package ah.szxy.observe2;
import java.util.Observable;
/**
* 1. 目标对象
* @author chy
*
*/
public class ConcreteSubject extends Observable {
private int state;
public void set(int s){
state = s; //目标对象的状态发生了改变
setChanged(); //表示目标对象已经做了更改
notifyObservers(state); //通知所有的观察者
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
package ah.szxy.observe2;
import java.util.Observable;
import java.util.Observer;
/**
* 2. 观察者实现类
* @author chy
*
*/
public class ObserverA implements Observer {
private int myState;
@Override
public void update(Observable o, Object arg) {
myState = ((ConcreteSubject)o).getState();
}
public int getMyState() {
return myState;
}
public void setMyState(int myState) {
this.myState = myState;
}
}
package ah.szxy.observe2;
/**
* 测试系统自带Observable接口实现的观察者模式
* @author 曹海洋
*
*/
public class Client {
public static void main(String[] args) {
//创建目标对象Obserable
ConcreteSubject subject = new ConcreteSubject();
//创建观察者
ObserverA obs1 = new ObserverA();
ObserverA obs2 = new ObserverA();
ObserverA obs3 = new ObserverA();
//将上面三个观察者对象添加到目标对象subject的观察者容器中
subject.addObserver(obs1);
subject.addObserver(obs2);
subject.addObserver(obs3);
//改变subject对象的状态
subject.set(3000);
System.out.println("===============状态修改了!");
//观察者的状态发生了变化
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
subject.set(600);
System.out.println("===============状态修改了!");
//观察者的状态发生了变化
System.out.println(obs1.getMyState());
System.out.println(obs2.getMyState());
System.out.println(obs3.getMyState());
}
}
测试结果
就是保存某个对象内部状态的拷贝,这样以后就可以将该对象恢复到原先的状态。 结构:
生活中的应用
开发中常见的应用场景
uml类图
package ah.szxy.memento;
/**
* 1 .源发器类
* @author chy
*
*/
public class Emp {
private String ename;
private int age;
private double salary;
/**
* 进行备忘操作,并返回备忘录对象
* @return
*/
public EmpMemento memento(){
return new EmpMemento(this);
}
/**
* 进行数据恢复,恢复成指定备忘录对象的值
* @param mmt
*/
public void recovery(EmpMemento mmt){
this.ename = mmt.getEname();
this.age = mmt.getAge();
this.salary = mmt.getSalary();
}
public Emp(String ename, int age, double salary) {
super();
this.ename = ename;
this.age = age;
this.salary = salary;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
package ah.szxy.memento;
/**
*2. 备忘录类
* @author chy
*
*/
public class EmpMemento {
private String ename;
private int age;
private double salary;
public EmpMemento(Emp e) {
this.ename = e.getEname();
this.age = e.getAge();
this.salary = e.getSalary();
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
package ah.szxy.memento;
/**
* 3. 负责人类
* 负责管理备忘录对象
* @author chy
*
*/
public class CareTaker {
private EmpMemento memento;
// private List<EmpMemento> list = new ArrayList<EmpMemento>();
// 可以通过容器设置多备忘点
public EmpMemento getMemento() {
return memento;
}
public void setMemento(EmpMemento memento) {
this.memento = memento;
}
}
package ah.szxy.memento;
/**
* 测试备忘录模式
* @author chy
*
*/
public class Client {
public static void main(String[] args) {
CareTaker taker = new CareTaker();
Emp emp = new Emp("chy", 24, 0);
System.out.println("第一次打印对象:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary());
taker.setMemento(emp.memento()); //备忘一次
emp.setAge(24);
emp.setEname("奋起");
emp.setSalary(18000);
System.out.println("第二次打印对象:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary());
emp.recovery(taker.getMemento()); //恢复到备忘录对象保存的状态
System.out.println("第三次打印对象:"+emp.getEname()+"---"+emp.getAge()+"---"+emp.getSalary());
}
}
测试结果
模式分类 | 作用 |
---|---|
职责链模式 | 避免请求发送者和接收者耦合,让多个对象都有可能接收请求,将这些对象连成一条链,并且沿着这条链传递请求,直到有对象处理为止 |
命令模式 | 将一个请求封装为一个对象,从而使得请求调用者和请求接收者解耦 |
解释器模式 | 描述如何为语言定义一个文法,如何解析 |
迭代器模式 | 提供了一种方法来访问聚合对象 |
中介者模式 | 通过一个中介对象来封装一系列的对象交互,使得各对象不需要相互引用 |
备忘录模式 | 捕获一个对象的内部状态,并保存之;需要时,可以恢复到保存的状态 |
观察者模式 | 当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新 |
状态模式 | 允许一个对象在其内部状态改变时改变它的行为 |
策略模式 | 定义一系列算法,并将每个算法封装在一个类中 |
模板方法 | 定义一个操作的算法骨架,将某些易变的步骤延迟到子类中实现 |
访问者模式 | 表示一个作用于某对象结构中的各元素的操作,它使得用户可以在不改变各元素的类的前提下定义作用于这些元素的新操作 |