设计模式——行为型设计模式

本文是学习尚硅谷韩顺平老师的图解设计模式后,自己做的笔记,代码都是照着视频敲得,不知道会不会有转载的嫌疑,若有,麻烦请提醒本人,谢谢!


1、模板模式

概述:

可以让一个类的行为或其算法可以在运行时更改的设计模式。

特点:

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对象。

策略对象改变 context 对象的执行算法。

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

把变化的代码从不变的代码分离出来。

针对接口表编程。

多用聚合少用继承。

角色:

1、方法接口

2、实现方法类

3、调用者(聚合实用方法类)

代码实现:


//1、创建接口 

public interface FlyBehavior {
	void fly();
}

//2、创建实现类
//此处即为方法簇的实现

public class GoodFlyBehavior implements FlyBehavior{

	public GoodFlyBehavior() {
		System.out.println("飞行能力好!");
	}

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		
	}

}



public class NoFlyBehavior implements FlyBehavior{

	public NoFlyBehavior() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void fly() {
		System.out.println("没有飞行能力!");
		
	}

}


public class WildDuck extends Duck{

	public WildDuck(FlyBehavior flybehavior) {
		super(flybehavior);
		
	}
	@Override
	public void disply() {
		// TODO Auto-generated method stub
		System.out.println("这是野鸭");
	}
	
}


3、创建使用对象


public abstract class Duck {

	private FlyBehavior flybehavior;

	public Duck(FlyBehavior flybehavior) {
		super();
		this.flybehavior = flybehavior;
	}	
	public abstract void disply();
	public void fly() {
		if (flybehavior!=null)
			flybehavior.fly();
	}
}



public class WildDuck extends Duck{

	public WildDuck(FlyBehavior flybehavior) {
		super(flybehavior);
		
	}
	@Override
	public void disply() {
		// TODO Auto-generated method stub
		System.out.println("这是野鸭");
	}
	
}



//4、客户端调用

public class client {

	public static void main(String[] args) {
		Duck duck = new WildDuck(new GoodFlyBehavior());
		duck.fly();
	}

}

2、命令模式

概述:

是一种数据驱动的设计模式。

特点:

请求以命令的形式包裹在对象中,并传给调用对象。

调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

接触命令发送者跟命令接受者的耦合关系,让对象间的调用更加灵活。

角色:

1、命令类接口

2、命令类实体类(内部聚合接收者类)

3、接收者类

4、命令者(聚合命令类实体)

代码实现:


//1、命令类接口
//创建命令接口
public interface Command {

	//执行动作
	public void execute();
	//取消动作
	public void undo();
}


//2、命令类实现类

public class LightOffCommand implements  Command{


	private LightReceiver light;
	
	
	public LightOffCommand(LightReceiver light) {
		super();
		this.light = light;
	}


	@Override
	public void execute() {
		// TODO Auto-generated method stub
		light.off();
	}

	@Override
	public void undo() {
		// TODO Auto-generated method stub
		light.on();
	}

}



public class LingtOnCommad implements  Command{

	//内部聚合信号接收者
	private LightReceiver light;
	
	
	public LingtOnCommad(LightReceiver light) {
		super();
		this.light = light;
	}

	@Override
	public void execute() {
		// TODO Auto-generated method stub
		light.on();
	}

	@Override
	public void undo() {
		// TODO Auto-generated method stub
		light.off();
	}

}


//3、命令接受处理者

//独立的执行者类
public class LightReceiver {

	public void on() {
		System.out.println("电灯打开了!");
		
	}
	
	public void off() {
		System.out.println("电灯关闭了!");
	}

}


//4、聚合控制器类,命令发布者类


//持有多个命令数组,用于调用命令

public class RemoteController {

	//开始的操作
	Command[] onCommands;
	Command[] offCommands;
	
	//取消的操作
	
	Command undoCommand;
	
	
	public RemoteController() {

		onCommands = new Command[5];
		offCommands = new Command[5];
		
		for (int i = 0; i < 5; i++) {

			onCommands[i] = new NoCommand();
			offCommands[i] = new NoCommand();
		}
	}
	
	//设置按钮
	
	public void setCommand(int no ,Command oncommand,Command offcommand) {
		onCommands[no] = oncommand;
		offCommands[no] = offcommand;
	}
	
	public void onButtonwasPushed(int no) {
		onCommands[no].execute();
		//执行操作后记住本次对象
		undoCommand = onCommands[no];
		
	}

	public void offButtonwasPushed(int no) {
		offCommands[no].execute();
		//执行操作后记住本次对象
		undoCommand = offCommands[no];
		
	}
	public void undoButtonwasPushed() {
		undoCommand.undo();
	}
}


//5、空对象类用于初始化


//空实现的对象用处初始化
public class NoCommand implements Command{

	
	public NoCommand() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void execute() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void undo() {
		// TODO Auto-generated method stub
		
	}

}


//6、客户端调用

public class Client {

public static void main(String[] args) {
	//利用命令模式通过遥控调用电视
	//创建接收者
	LightReceiver lightreceiver = new LightReceiver();
	
	//创建开关信号
	LingtOnCommad lightoncommand = new LingtOnCommad(lightreceiver);
	LightOffCommand lightoffcommand = new LightOffCommand(lightreceiver);
	
	RemoteController remotecontroller = new RemoteController();
	
	remotecontroller.setCommand(0, lightoncommand, lightoffcommand);
	
	System.out.println("-------按下开的按钮!-----------");
	remotecontroller.onButtonwasPushed(0);
	System.out.println("-------按下关的按钮!-----------");
	remotecontroller.offButtonwasPushed(0);
	System.out.println("-------按下取消的按钮!-----------");
	remotecontroller.undoButtonwasPushed();
	
	
}
}

3、访问者模式

概述:

一种使用了一个访问者类来改变了元素类的执行算法的设计模式。

特点:

封装一些作用与某种数据结构的各元素的操作,可以在不改变数据结构的前提下重新定义作用与这些元素的新操作。

解决数据结构跟操做耦合性问题。

在被访问的类里面加一个对外提供访问者的接口。

您在朋友家做客,您是访问者,朋友接受您的访问,您通过朋友的描述,然后对朋友的描述做出一个判断,这就是访问者模式。

角色:

1、抽象访问者:对数据结构进行操作

2、实体访问者

3、抽象元素类:提供一个aceept方法来接受访问者

4、具体元素类

5、ObjectStructure:能枚举他的元素,提供一个高层接口,用来允许访问者访问元素

代码实现:

//1、创建抽象访问者


//抽象访问者类
public abstract class Action {

	//获得某种操作结果
	public abstract void getManResult(Man man );

	//获得某种操作结果
	public abstract void getWomenResult(Women women);
}


//2、实体访问者

public class Success extends Action{

	@Override
	public void getManResult(Man man) {
		System.out.println("男性成功!");
		
	}

	@Override
	public void getWomenResult(Women women) {
		System.out.println("女性成功 !");
	}

}


public class Fail extends Action{

	@Override
	public void getManResult(Man man) {
	System.out.println("男人评价失败!");
	}

	@Override
	public void getWomenResult(Women women) {
			System.out.println("女人评价失败!");
	}

}


//3、创建实体类

public abstract class Person {

	public abstract void accept(Action action);
}


//使用了双分配,获得对象进来,把自己传出去。
public class Women extends Person{

	@Override
	public void accept(Action action) {
		action.getWomenResult(this);
	}

}


public class Man extends Person{

	@Override
	public void accept(Action action) {
		action.getManResult(this);	
	}
	
	

}



//4、创建缓冲层

public class ObjectStructure {

	//维护一个集合
	
	private LinkedList<Person> persons = new LinkedList<Person>();
	
	//增加进去 
	
	public void attach(Person p ) {
		persons.add(p);
	}
	
	public void detach(Person p) {
		persons.remove(p);
	}
	
	//显示
	public void display(Action action) {
		for(Person p:persons) {
			p.accept(action);
		}
	}
}


//5、调用
public class Client {

	public static void main(String[] args) {
		ObjectStructure objectstructure = new ObjectStructure();
		
		objectstructure.attach(new Man());
		objectstructure.attach(new Man());
		objectstructure.attach(new Man());
		
		
		Success success = new Success();
		
		objectstructure.display(success);
	}
}

4、迭代器模式

概述:

一种用于顺序访问集合对象的元素,不需要知道集合对象的底层表示的设计模式。

特点:

提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。

实现多种数据结构的遍历而不用了解其内部结构。

代码实现:

用Iterator实现:

1、实现Iterator接口的方法。

2、统一的聚合接口。将客户端和具体的聚合解耦。

3、聚合接口实体类:持有具体的对象集合。

4、Interator实体类:目标对象。

1、创建对象类。

public class Department {

	private String name;
	private String desc;
	public Department(String name, String desc) {
		super();
		this.name = name;
		this.desc = desc;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}
	
}


2、实现Iterator方法,分情况实现hasNext跟next。

public class ComputerCollegeIterator implements Iterator{

	//这里需要Department,以对应形式存放
	Department[] departments;
	int position = 0;
	public ComputerCollegeIterator(Department[] departments) {
		super();
		this.departments = departments;
	}

	@Override
	public boolean hasNext() {
		if(position>=departments.length||departments[position]==null) {
			return false; 
		}else {
		return true;
		}
	}

	@Override
	public Object next() {
		Department department = departments[position];
		position++;
		return null;
	}


}



public class InfoCollegeIterator implements Iterator{

	List<Department> departmentlist;

	int index = -1;
	public InfoCollegeIterator(List<Department> departmentlist) {
		super();
		this.departmentlist = departmentlist;
	}

	@Override
	public boolean hasNext() {
		if(index >= departmentlist.size()-1) {
			return false;
		}else {
			index++; 
			return  true;
		}
		
	}

	@Override
	public Object next() {
		departmentlist.get(index);
		return null;
	}
	

}


//3、创建聚合类接口

public interface College {
	
	public String getName();
	
	//增加系的方法
	public void addDepartment(String name, String desc);
	
	//返回一个迭代器,遍历
	public Iterator  createIterator();
}


//4、实现聚合类

public class ComputerCollege implements College {

	Department[] departments;
	int numOfDepartment = 0 ;// 保存当前数组的对象个数
	
	
	public ComputerCollege() {
		departments = new Department[5];
		addDepartment("Java专业", " Java专业 ");
		addDepartment("PHP专业", " PHP专业 ");
		addDepartment("大数据专业", " 大数据专业 ");
		
	}
	
	
	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return "计算机学院";
	}

	@Override
	public void addDepartment(String name, String desc) {
		// TODO Auto-generated method stub
		Department department = new Department(name, desc);
		departments[numOfDepartment] = department;
		numOfDepartment += 1;
	}

	@Override
	public Iterator createIterator() {
		// TODO Auto-generated method stub
		return new ComputerCollegeIterator(departments);
	}

}



public class InfoCollege implements College {

	List<Department> departmentList;
	
	
	public InfoCollege() {
		departmentList = new ArrayList<Department>();
		addDepartment("信息安全专业", " 信息安全专业 ");
		addDepartment("网络安全专业", " 网络安全专业 ");
		addDepartment("服务器安全专业", " 服务器安全专业 ");
	}
	
	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return "信息工程学院";
	}

	@Override
	public void addDepartment(String name, String desc) {
		// TODO Auto-generated method stub
		Department department = new Department(name, desc);
		departmentList.add(department);
	}

	@Override
	public Iterator createIterator() {
		// TODO Auto-generated method stub
		return new InfoCollegeIterator(departmentList);
	}

}


//5、输出类

public class OutPutImpl {
	
	//学院集合
	List<College> collegeList;

	public OutPutImpl(List<College> collegeList) {
		
		this.collegeList = collegeList;
	}
	//遍历所有学院,然后调用printDepartment 输出各个学院的系
	public void printCollege() {
		
		//从collegeList 取出所有学院, Java 中的 List 已经实现Iterator
		Iterator<College> iterator = collegeList.iterator();
		
		while(iterator.hasNext()) {
			//取出一个学院
			College college = iterator.next();
			System.out.println("=== "+college.getName() +"=====" );
			printDepartment(college.createIterator()); //得到对应迭代器
		}
	}
	
	
	//输出 学院输出 系
	
	public void printDepartment(Iterator iterator) {
		while(iterator.hasNext()) {
			Department d = (Department)iterator.next();
			System.out.println(d.getName());
		}
	}
	
}


//6、客户端调用

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建学院
		List<College> collegeList = new ArrayList<College>();
		
		ComputerCollege computerCollege = new ComputerCollege();
		InfoCollege infoCollege = new InfoCollege();
		
		collegeList.add(computerCollege);
		//collegeList.add(infoCollege);
		
		OutPutImpl outPutImpl = new OutPutImpl(collegeList);
		outPutImpl.printCollege();
	}

}



5、观察者模式

概述:

特点:

角色:

代码实现:

6、中介者模式

概述:

一种是用来降低多个对象和类之间的通信复杂性的设计模式。

特点:

用一个对象来封装一系列的对象交互,使各个对象之间无需显示地相互作用,从而使耦合松散,而且可以独立改变他们之间地交互。

使网状结构变成星型结构。

角色:

1、中介者(管理对象,完成对象操作和任务)

2、实体对象

3、客户端:通过中介者调用实体对象

代码实现:

//1、创建抽象实体类

//同事抽象类
public abstract class Colleague {
	private Mediator mediator;
	public String name;

	public Colleague(Mediator mediator, String name) {

		this.mediator = mediator;
		this.name = name;

	}

	public Mediator GetMediator() {
		return this.mediator;
	}

	public abstract void SendMessage(int stateChange);
}


//2、创建实体类

public class Curtains extends Colleague {

	public Curtains(Mediator mediator, String name) {
		super(mediator, name);
		// TODO Auto-generated constructor stub
		mediator.Register(name, this);
	}

	@Override
	public void SendMessage(int stateChange) {
		// TODO Auto-generated method stub
		this.GetMediator().GetMessage(stateChange, this.name);
	}

	public void UpCurtains() {
		System.out.println("I am holding Up Curtains!");
	}

}


public class CoffeeMachine extends Colleague {

	public CoffeeMachine(Mediator mediator, String name) {
		super(mediator, name);
		// TODO Auto-generated constructor stub
		mediator.Register(name, this);
	}

	@Override
	public void SendMessage(int stateChange) {
		// TODO Auto-generated method stub
		this.GetMediator().GetMessage(stateChange, this.name);
	}

	public void StartCoffee() {
		System.out.println("It's time to startcoffee!");
	}

	public void FinishCoffee() {

		System.out.println("After 5 minutes!");
		System.out.println("Coffee is ok!");
		SendMessage(0);
	}
}



public class TV extends Colleague {

	public TV(Mediator mediator, String name) {
		super(mediator, name);
		// TODO Auto-generated constructor stub
		mediator.Register(name, this);
	}

	@Override
	public void SendMessage(int stateChange) {
		// TODO Auto-generated method stub
		this.GetMediator().GetMessage(stateChange, this.name);
	}

	public void StartTv() {
		// TODO Auto-generated method stub
		System.out.println("It's time to StartTv!");
	}

	public void StopTv() {
		// TODO Auto-generated method stub
		System.out.println("StopTv!");
	}
}





//具体的同事类
public class Alarm extends Colleague {

	//构造器
	public Alarm(Mediator mediator, String name) {
		super(mediator, name);
		// TODO Auto-generated constructor stub
		//在创建Alarm 同事对象时,将自己放入到ConcreteMediator 对象中[集合]
		mediator.Register(name, this);
	}

	public void SendAlarm(int stateChange) {
		SendMessage(stateChange);
	}

	@Override
	public void SendMessage(int stateChange) {
		// TODO Auto-generated method stub
		//调用的中介者对象的getMessage
		this.GetMediator().GetMessage(stateChange, this.name);
	}

}


//3、中介者抽象类

public abstract class Mediator {
	//将给中介者对象,加入到集合中
	public abstract void Register(String colleagueName, Colleague colleague);

	//接收消息, 具体的同事对象发出
	public abstract void GetMessage(int stateChange, String colleagueName);

	public abstract void SendMessage();
}



//4、实体中介者类

//具体的中介者类
public class ConcreteMediator extends Mediator {
	//集合,放入所有的同事对象
	private HashMap<String, Colleague> colleagueMap;
	private HashMap<String, String> interMap;

	public ConcreteMediator() {
		colleagueMap = new HashMap<String, Colleague>();
		interMap = new HashMap<String, String>();
	}

	@Override
	public void Register(String colleagueName, Colleague colleague) {
		// TODO Auto-generated method stub
		colleagueMap.put(colleagueName, colleague);

		// TODO Auto-generated method stub

		if (colleague instanceof Alarm) {
			interMap.put("Alarm", colleagueName);
		} else if (colleague instanceof CoffeeMachine) {
			interMap.put("CoffeeMachine", colleagueName);
		} else if (colleague instanceof TV) {
			interMap.put("TV", colleagueName);
		} else if (colleague instanceof Curtains) {
			interMap.put("Curtains", colleagueName);
		}

	}

	//具体中介者的核心方法
	//1. 根据得到消息,完成对应任务
	//2. 中介者在这个方法,协调各个具体的同事对象,完成任务
	@Override
	public void GetMessage(int stateChange, String colleagueName) {
		// TODO Auto-generated method stub

		//处理闹钟发出的消息
		if (colleagueMap.get(colleagueName) instanceof Alarm) {
			if (stateChange == 0) {
				((CoffeeMachine) (colleagueMap.get(interMap
						.get("CoffeeMachine")))).StartCoffee();
				((TV) (colleagueMap.get(interMap.get("TV")))).StartTv();
			} else if (stateChange == 1) {
				((TV) (colleagueMap.get(interMap.get("TV")))).StopTv();
			}

		} else if (colleagueMap.get(colleagueName) instanceof CoffeeMachine) {
			((Curtains) (colleagueMap.get(interMap.get("Curtains"))))
					.UpCurtains();

		} else if (colleagueMap.get(colleagueName) instanceof TV) {//如果TV发现消息

		} else if (colleagueMap.get(colleagueName) instanceof Curtains) {
			//如果是以窗帘发出的消息,这里处理...
		}

	}

	@Override
	public void SendMessage() {
		// TODO Auto-generated method stub

	}

}


//5、客户端调用

public class ClientTest {

	public static void main(String[] args) {
		//创建一个中介者对象
		Mediator mediator = new ConcreteMediator();
		
		//创建Alarm 并且加入到  ConcreteMediator 对象的HashMap
		Alarm alarm = new Alarm(mediator, "alarm");
		
		//创建了CoffeeMachine 对象,并  且加入到  ConcreteMediator 对象的HashMap
		CoffeeMachine coffeeMachine = new CoffeeMachine(mediator,
				"coffeeMachine");
		
		//创建 Curtains , 并  且加入到  ConcreteMediator 对象的HashMap
		Curtains curtains = new Curtains(mediator, "curtains");
		TV tV = new TV(mediator, "TV");
		
		//让闹钟发出消息
		alarm.SendAlarm(0);
		coffeeMachine.FinishCoffee();
		alarm.SendAlarm(1);
	}

}

7、备忘录模式

概述:

一种可以存一个对象的某个状态,以便在适当的时候恢复对象的设计模式。

特点:

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

通过一个备忘录类专门存储对象状态。

客户不与备忘录类耦合,与备忘录管理类耦合。

角色:

1、原始对象类

2、状态保存类(内置要保存属性)

3、状态保存类管理者(聚合状态保存类)

4、客户端

代码实现:

//1、创建原始对象类

public class Originator {

	private String state;   //状态信息

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}
	
	//获得一个状态保存类
	public Memento savaStateMemento(){
		return new Memento(state);
	}

	//从状态保存类中获取状态信息
	
	public void getStateFromMemento(Memento memento) {
		state = memento.getState();
	}
}

//2、创建对象保存类

public class Memento {

	private String state;

	public Memento(String state) {
		super();
		this.state = state;
	}
	public String  getState() {
		return state;
	}


}


//3、创建保存管理类

public class Caretaker {

	private List<Memento> mementolist = new ArrayList<Memento>();
	
	public void add(Memento memento) {
		mementolist.add(memento);
	}
	
	public Memento get(int index) {
		return mementolist.get(index);
	}

}

//4、客户端调用

public class Client {

	public static void main(String[] args) {
		Originator originator = new Originator();
		
		Caretaker caretaker = new Caretaker();
		originator.setState("状态1!");
		caretaker.add(originator.savaStateMemento());
		originator.setState("状态2!");
		caretaker.add(originator.savaStateMemento());		
		originator.setState("状态3!");
		caretaker.add(originator.savaStateMemento());
		System.out.println("现在的状态是:"+originator.getState());
		System.out.println("回复状态!");
		originator.setState(caretaker.get(0).getState());
		System.out.println("现在的状态是:"+originator.getState());
	}

}

8、解释器模式

概述:

一种提供了评估语言的语法或表达式的方式的设计模式。

特点:

这种模式实现了一个表达式接口,该接口解释一个特定的上下文。

给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。

可扩展性比较好,灵活。

增加了新的解释表达式的方式。

易于实现简单文法。

角色:

1、上下文类

2、抽象表达式解析类

3、表达式实现类

代码实现:

实现判断语句

//1、创建表达式接口

public interface Expression {
   public boolean interpret(String context);
}

//2、实现接口

public class TerminalExpression implements Expression {
   
   private String data;
 
   public TerminalExpression(String data){
      this.data = data; 
   }
 
   @Override
   public boolean interpret(String context) {
      if(context.contains(data)){
         return true;
      }
      return false;
   }
}



public class OrExpression implements Expression {
    
   private Expression expr1 = null;
   private Expression expr2 = null;
 
   public OrExpression(Expression expr1, Expression expr2) { 
      this.expr1 = expr1;
      this.expr2 = expr2;
   }
 
   @Override
   public boolean interpret(String context) {      
      return expr1.interpret(context) || expr2.interpret(context);
   }
}


public class AndExpression implements Expression {
    
   private Expression expr1 = null;
   private Expression expr2 = null;
 
   public AndExpression(Expression expr1, Expression expr2) { 
      this.expr1 = expr1;
      this.expr2 = expr2;
   }
 
   @Override
   public boolean interpret(String context) {      
      return expr1.interpret(context) && expr2.interpret(context);
   }
}


//4、调用
public class InterpreterPatternDemo {
 
   //规则:Robert 和 John 是男性
   public static Expression getMaleExpression(){
      Expression robert = new TerminalExpression("Robert");
      Expression john = new TerminalExpression("John");
      return new OrExpression(robert, john);    
   }
 
   //规则:Julie 是一个已婚的女性
   public static Expression getMarriedWomanExpression(){
      Expression julie = new TerminalExpression("Julie");
      Expression married = new TerminalExpression("Married");
      return new AndExpression(julie, married);    
   }
 
   public static void main(String[] args) {
      Expression isMale = getMaleExpression();
      Expression isMarriedWoman = getMarriedWomanExpression();
 
      System.out.println("John is male? " + isMale.interpret("John"));
      System.out.println("Julie is a married women? " 
      + isMarriedWoman.interpret("Married Julie"));
   }
}

9、状态模式

概述:

一种类的行为是基于它的状态改变的设计模式。

特点:

允许对象在内部状态发生改变时改变它的行为。

对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

可以解决代码中包含大量与对象状态有关的条件语句。

当一个对象的内在状态改变时,允许改变其行为。看起来像是改变了其类。

使用时要先分析出所有状态。

角色:

1、环境角色类:用于维护State实例,这个实例定义当前状态

2、抽象状态角色类:定义一个接口封装与环境

3、实体状态角色类:为每一状态添加具体行为

代码实现:

//1、创建状态抽象类

public abstract class State {

	
	// 扣除积分 - 50
    public abstract void deductMoney();

    // 是否抽中奖品
    public abstract boolean raffle();

    // 发放奖品
    public abstract  void dispensePrize();

}


//2、创建状态实体类

public class NoRaffleState extends State {

	 // 初始化时传入活动引用,扣除积分后改变其状态
    RaffleActivity activity;

    public NoRaffleState(RaffleActivity activity) {
        this.activity = activity;
    }

    // 当前状态可以扣积分 , 扣除后,将状态设置成可以抽奖状态
    @Override
    public void deductMoney() {
        System.out.println("扣除50积分成功,您可以抽奖了");
        activity.setState(activity.getCanRaffleState());
    }

    // 当前状态不能抽奖
    @Override
    public boolean raffle() {
        System.out.println("扣了积分才能抽奖喔!");
        return false;
    }

    // 当前状态不能发奖品
    @Override
    public void dispensePrize() {
        System.out.println("不能发放奖品");
    }
}



public class DispenseState extends State {

	 // 初始化时传入活动引用,发放奖品后改变其状态
    RaffleActivity activity;

    public DispenseState(RaffleActivity activity) {
        this.activity = activity;
    }
    
    //

    @Override
    public void deductMoney() {
        System.out.println("不能扣除积分");
    }

    @Override
    public boolean raffle() {
        System.out.println("不能抽奖");
        return false;
    }

    //发放奖品
    @Override
    public void dispensePrize() {
        if(activity.getCount() > 0){
            System.out.println("恭喜中奖了");
            // 改变状态为不能抽奖
            activity.setState(activity.getNoRafflleState());
        }else{
            System.out.println("很遗憾,奖品发送完了");
            // 改变状态为奖品发送完毕, 后面我们就不可以抽奖
            activity.setState(activity.getDispensOutState());
            //System.out.println("抽奖活动结束");
            //System.exit(0);
        }

    }
}



public class DispenseOutState extends State {

	// 初始化时传入活动引用
    RaffleActivity activity;

    public DispenseOutState(RaffleActivity activity) {
        this.activity = activity;
    }
    @Override
    public void deductMoney() {
        System.out.println("奖品发送完了,请下次再参加");
    }

    @Override
    public boolean raffle() {
        System.out.println("奖品发送完了,请下次再参加");
        return false;
    }

    @Override
    public void dispensePrize() {
        System.out.println("奖品发送完了,请下次再参加");
    }
}



public class CanRaffleState extends State {

    RaffleActivity activity;

    public CanRaffleState(RaffleActivity activity) {
        this.activity = activity;
    }

    //已经扣除了积分,不能再扣
    @Override
    public void deductMoney() {
        System.out.println("已经扣取过了积分");
    }

    //可以抽奖, 抽完奖后,根据实际情况,改成新的状态
    @Override
    public boolean raffle() {
        System.out.println("正在抽奖,请稍等!");
        Random r = new Random();
        int num = r.nextInt(10);
        // 10%中奖机会
        if(num == 0){
            // 改变活动状态为发放奖品 context
            activity.setState(activity.getDispenseState());
            return true;
        }else{
            System.out.println("很遗憾没有抽中奖品!");
            // 改变状态为不能抽奖
            activity.setState(activity.getNoRafflleState());
            return false;
        }
    }

    // 不能发放奖品
    @Override
    public void dispensePrize() {
        System.out.println("没中奖,不能发放奖品");
    }
}




//3、创建主题活动

public class RaffleActivity {

	// state 表示活动当前的状态,是变化
    State state = null;
    // 奖品数量
    int count = 0;
    
    // 四个属性,表示四种状态
    State noRafflleState = new NoRaffleState(this);
    State canRaffleState = new CanRaffleState(this);
    
    State dispenseState =   new DispenseState(this);
    State dispensOutState = new DispenseOutState(this);

    //构造器
    //1. 初始化当前的状态为 noRafflleState(即不能抽奖的状态)
    //2. 初始化奖品的数量 
    public RaffleActivity( int count) {
        this.state = getNoRafflleState();
        this.count = count;
    }

    //扣分, 调用当前状态的 deductMoney
    public void debuctMoney(){
        state.deductMoney();
    }

    //抽奖 
    public void raffle(){
    	// 如果当前的状态是抽奖成功
        if(state.raffle()){
        	//领取奖品
            state.dispensePrize();
        }

    }

    public State getState() {
        return state;
    }

    public void setState(State state) {
        this.state = state;
    }

    //这里请大家注意,每领取一次奖品,count--
    public int getCount() {
    	int curCount = count; 
    	count--;
        return curCount;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public State getNoRafflleState() {
        return noRafflleState;
    }

    public void setNoRafflleState(State noRafflleState) {
        this.noRafflleState = noRafflleState;
    }

    public State getCanRaffleState() {
        return canRaffleState;
    }

    public void setCanRaffleState(State canRaffleState) {
        this.canRaffleState = canRaffleState;
    }

    public State getDispenseState() {
        return dispenseState;
    }

    public void setDispenseState(State dispenseState) {
        this.dispenseState = dispenseState;
    }

    public State getDispensOutState() {
        return dispensOutState;
    }

    public void setDispensOutState(State dispensOutState) {
        this.dispensOutState = dispensOutState;
    }
}


//4、创建客户端

public class ClientTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 创建活动对象,奖品有1个奖品
        RaffleActivity activity = new RaffleActivity(1);

        // 我们连续抽300次奖
        for (int i = 0; i < 30; i++) {
            System.out.println("--------第" + (i + 1) + "次抽奖----------");
            // 参加抽奖,第一步点击扣除积分
            activity.debuctMoney();

            // 第二步抽奖
            activity.raffle();
        }
	}

}

10、策略者模式

概述:

一种个类的行为或其算法可以在运行时更改的设计模式。

特点:

创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

让算法变化独立与使用算法的用户。

把变化的代码从不变的代码中分离开来,针对接口编程而不是具体类,多用组合聚合,少用继承。

角色:

1、策略接口

2、具体策略实现类

3、客户端:聚合策略接口

代码实现:

优点:

1、算法可以自由切换。

2、避免使用多重条件判断。

3、扩展性良好。

缺点:

1、策略类会增多。

2、所有策略类都需要对外暴露。


//1、策略接口

public interface FlyBehavior {
	void fly();
}


//2、策略实现类

public class NoFlyBehavior implements FlyBehavior{

	public NoFlyBehavior() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void fly() {
		System.out.println("没有飞行能力!");
		
	}

}



public class GoodFlyBehavior implements FlyBehavior{

	public GoodFlyBehavior() {
	
	}

	@Override
	public void fly() {
		System.out.println("飞行能力好!");
		
	}

}


//3、对象类

public abstract class Duck {

	private FlyBehavior flybehavior;

	public Duck(FlyBehavior flybehavior) {
		super();
		this.flybehavior = flybehavior;
	}	
	public abstract void disply();
	public void fly() {
		if (flybehavior!=null)
			flybehavior.fly();
	}
}


//4、客户端调用

public class client {

	public static void main(String[] args) {
		Duck duck = new WildDuck(new GoodFlyBehavior());
		duck.fly();
	}

}



11、职责链模式

概述:

一种为请求创建了一个接收者对象的链的设计模式。

特点:

给予请求的类型,对请求的发送者和接收者进行解耦。

每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

角色:

1、抽象请求接收/处理者类(内部聚合自己)

2、实体请求接收/处理者类

3、请求发送类

代码实现:

//1、创建请求类

public class PurchaseRequest {

	private int type = 0; //请求类型
	private float price = 0.0f;
	private int id = 0;
	public PurchaseRequest(int type, float price, int id) {
		super();
		this.type = type;
		this.price = price;
		this.id = id;
	}
	public int getType() {
		return type;
	}
	public void setType(int type) {
		this.type = type;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	
}

//2、创建抽象请求接受类

public abstract class Approver {

	Approver approver;  //下一个处理者
	String name;
	
	public Approver(String name) {
		this.name = name;
	}
	
	//下一个处理者
	public void setApprover(Approver approver) {
		this.approver = approver;
	}
	
	//处理审批请求的方法,得到一个请求,处理是子类完成,因此本方法做成抽象
	public abstract void processRequest(PurchaseRequest purchaserequest);
}


//3、创建实体请求类

public class CollegeApprover extends Approver{

	public CollegeApprover(String name) {
		super(name);
	}

	@Override
	public void processRequest(PurchaseRequest purchaserequest) {
		if(purchaserequest.getPrice()>5000&&purchaserequest.getPrice()<=10000) {
			System.out.println("请求编号:"+purchaserequest.getId()+"被"+this.name+"处理!");
			
		}else {
			approver.processRequest(purchaserequest);
		}
		
	}
	

}


public class DepartmentApprover extends Approver {

	public DepartmentApprover(String name) {
		super(name);
	}

	@Override
	public void processRequest(PurchaseRequest purchaserequest) {

		if(purchaserequest.getPrice()<=5000) {
			System.out.println("请求编号:"+purchaserequest.getId()+"被"+this.name+"处理!");
			
		}else {
			approver.processRequest(purchaserequest);
		}
	}

	
}


public class SchoolMasterApprover extends Approver{

	public SchoolMasterApprover(String name) {
		super(name);
	}

	@Override
	public void processRequest(PurchaseRequest purchaserequest) {
		if(purchaserequest.getPrice()>=10000) {
			System.out.println("请求编号:"+purchaserequest.getId()+"被"+this.name+"处理!");
			
		}else {
			approver.processRequest(purchaserequest);
		}	
		
	}

}


//4、客户端调用

public class Client {
	public static void main(String[] args) {
		//创建请求类
		PurchaseRequest purchaserequest = new PurchaseRequest(1, 9999, 1);
		
		//创建审批人
		DepartmentApprover departmentapprover  = new DepartmentApprover("张主任");
		CollegeApprover collegeapprover = new CollegeApprover("胡院长");
		SchoolMasterApprover master = new SchoolMasterApprover("陈校长");
		
		//设置链状处理对象
		departmentapprover.setApprover(collegeapprover);
		collegeapprover.setApprover(master);
		
		//开始处理
		departmentapprover.processRequest(purchaserequest);
	}
}


优点:
1、降低耦合度。它将请求的发送者和接收者解耦。

2、简化了对象。使得对象不需要知道链的结构。

3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。

4、增加新的请求处理类很方便。

缺点:

1、不能保证请求一定被接收。

2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。

3、可能不容易观察运行时的特征,有碍于除错。

猜你喜欢

转载自blog.csdn.net/Nimrod__/article/details/112617700