感言:今天这篇行为型设计模式写完了,就写了三篇设计模式相关文章了,完成了设计模式的部分学习了。每一个设计模式自己都写了一个很小的Demo,当然这些Demo也是参考了很多其他人写的博客以及一些书籍汇总产生的。总体来说给我的感觉是我面向对象的抽象能力有了很大的提升。对于接口,继承,封装等有了更加深入的理解,但是坦率的讲自己对设计模式的理解还不够强,还需得有更多的实践来将理论上的东西进行进一步的落实。
行为型模式:行为型模式设计到了算法和对象间职责的分配,行为模式描述了对象和类的模式,以及他们的通信模式,行为模式刻画了在程序运行时难以跟踪的复杂复杂的控制流可以分为行为类模式和行为类对象模式。将程序解耦,达到使系统升级性和维护性提高的目的。
行为型模式共有11种,分别对11种进行一个介绍 :
//创建接口Strategy,里面具有一个操作的function
public interface Strategy {
public int Operation(int left,int right);
}
//实现Strategy 接口
public class MultiplyOperation implements Strategy{
@Override
public int Operation(int left, int right) {
return left*right;
}
}
public class SubstractOperation implements Strategy{
@Override
public int Operation(int left, int right) {
return left-right;
}
}
//Context 会调用Strategy的Operation
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int execute(int left,int right){
return strategy.Operation(left,right);
}
}
public class Demo {
public static void main(String[] args){
int left = 5;
int right = 10;
Context context=new Context(new AddOperation());
System.out.println("Use add operation left+right = "+context.execute(left,right));
context = new Context(new SubstractOperation());
System.out.println("Use substract operation left-right = "+context.execute(left,right));
}
}
//console输出
Use add operation left+right = 15
Use substract operation left-right = -5
分析: 我们使用Context类进行计算,但是我们给他传入了不同的计算算法进去。过程都是一样的。策略模式可以让客户端传入计算的算法,方便合理的去替换和增加算法。我们都调用的是Context.execute函数,当我们传入AddOperation和Substract Operation的时候参生了不同的结果。
//定义抽象函数Template 几个抽象方法和
一个调用几个抽象方法的类
public abstract class Template {
abstract void weakUp();
abstract void lunch();
abstract void sleep();
public final void holdDay(){
weakUp();
lunch();
sleep();
}
}
public class Cat extends Template{
@Override
void weakUp() {
System.out.println("I am cat weak up at the evening");
}
@Override
void lunch() {
System.out.println("I eat mouse");
}
@Override
void sleep() {
System.out.println("I sleep in the morning");
}
}
public class Pig extends Template{
@Override
void weakUp() {
System.out.println("I am Pig,I weak up in the morning");
}
@Override
void lunch() {
System.out.println("I can eat everything in the afternoon");
}
@Override
void sleep() {
System.out.println("I sleep after lunch");
}
}
public class Demo {
public static void main(String[] args){
Template cat =new Cat();
Template pig =new Pig();
cat.holdDay();
System.out.println();
pig.holdDay();
}
}
//输出结果
I am cat weak up at the evening
I eat mouse
I sleep in the morning
I am Pig,I weak up in the morning
I can eat everything in the afternoon
I sleep after lunch
分析: 定义了模板方法,定义了三个抽象函数,weakup,lunch,sleep ,和对外提供的一个函数holeday。子类cat和pig都继承于模板。然后都实现了抽象函数,然后再Demo里面我们可以看到调用Cat对象和Pig对象的holdDay最后就会有不同的结果。
public abstract class Observer {
protected Subject subject;
public abstract void update(String message);
}
public class ManObserver extends Observer{
public ManObserver(Subject subject) {
this.subject = subject;
}
@Override
public void update(String message) {
if(message.equalsIgnoreCase("man")){
System.out.println("我是男人,我接受到消息");
}else {
System.out.println("我是男人,我接到到消息,但是不做任何事情");
}
}
}
public class WomenObserver extends Observer{
public WomenObserver(Subject subject) {
this.subject = subject;
}
@Override
public void update(String message) {
if(message.equalsIgnoreCase("man")){
System.out.println("我是女人,我接受到消息,但是不做任何事情");
}else {
System.out.println("我是女人,我接到到消息");
}
}
}
public class Subject {
private List observers = new ArrayList<>();
public void attach(Observer observer){
observers.add(observer);
}
public void notifyAllObservers(String message){
for(Observer observer:observers){
observer.update(message);
}
}
}
public class Demo {
public static void main(String[] args){
Subject subject =new Subject();
ManObserver manObserver =new ManObserver(subject);
subject.attach(manObserver);
WomenObserver womenObserver=new WomenObserver(subject);
subject.attach(womenObserver);
subject.notifyAllObservers("man");
System.out.println("---------");
subject.notifyAllObservers("woman");
}
}
//输出结果
我是男人,我接受到消息
我是女人,我接受到消息,但是不做任何事情
---------
我是男人,我接到到消息,但是不做任何事情
我是女人,我接到到消息
分析: 有两个观察者,他们都去订阅Subject的内容。当Subject有消息通知观察者的时候,观察者就能够获取到消息并做相应的处理。Subject对象有两个观察者,而且当他通知给man观察者的时候。woman观察者接受到了消息,但是不做任何操作。man观察者接受到了消息就做了相应的操作。输出的结果也很预期一致。(看我博客Spring-boot使用Quartz实现多线程调度任务 当中就用到了观察者模式进行处理)
public interface Container {
public Iterator getIterator();
}
public interface Iterator {
public boolean hasNext();
public Object next();
}
public class NameRepository implements Container{
public String names[] = {"Robert","John","Julie","Lora"};
@Override
public Iterator getIterator(){
return new NameIterator();
}
private class NameIterator implements Iterator{
int index;
@Override
public boolean hasNext(){
if(index
分析: 自己实现了一个Iterator来遍历数组。
//用JAVA常用的日志来说明问题
public abstract class AbstractLogger {
//定义3种优先级的日志
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
protected AbstractLogger nextLogger;
public void setNextLogger(AbstractLogger nextLogger){
this.nextLogger = nextLogger;
}
public void logMessage(int level,String message){
if(this.level<=level){
write(message);
}
if(nextLogger!=null){
nextLogger.logMessage(level,message);
}
}
abstract protected void write(String message);
}
//创建3个类,分别继承抽象类,实现抽象方法
public class ConsoleLogger extends AbstractLogger{
public ConsoleLogger(int level){
this.level = level;
}
@Override
protected void write(String message){
System.out.println("Standard Console:Logger"+message);
}
}
public class DebugLogger extends AbstractLogger{
public DebugLogger(int level){
this.level = level;
}
@Override
protected void write(String message){
System.out.println("Debug logger:Logger" + message);
}
}
public class ErrorLogger extends AbstractLogger{
public ErrorLogger(int level){
this.level = level;
}
protected void write(String message){
System.out.println("Error Console:Logger"+message);
}
}
public class Demo {
public static AbstractLogger getChainOfLoggers(){
AbstractLogger console = new ConsoleLogger(AbstractLogger.INFO);
AbstractLogger debug = new DebugLogger(AbstractLogger.DEBUG);
AbstractLogger error = new ErrorLogger(AbstractLogger.ERROR);
error.setNextLogger(debug);
debug.setNextLogger(console);
return error;
}
public static void main(String[] args){
AbstractLogger loggerChain = getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.INFO,"This is info level");
loggerChain.logMessage(AbstractLogger.DEBUG,"This is debug level");
loggerChain.logMessage(AbstractLogger.ERROR,"This is error level");
}
}
//输出结果
Standard Console:LoggerThis is info level
Debug logger:LoggerThis is debug level
Standard Console:LoggerThis is debug level
Error Console:LoggerThis is error level
Debug logger:LoggerThis is error level
Standard Console:LoggerThis is error level
分析:定义了3种优先级的Logger,然后通过判断Logger的优先级来判断是否输出结果。当优先级高时就会多次输出结果,就像链一样,一个一个的挨着去比较,如果合适就进行相应的操作。在Spring中的Interceptor也是采用这种模式。(Spring和其他的大型框架里面将设计模式用得比较的透彻。我们将谁急模式学习好了,在看和理解一下大型的框架时就能够更好的去理解了。)
//接口Command
public interface Command {
void execute();
}
//Command实现类
public class ConcreteCommand implements Command{
private Receiver receiver = null;
public ConcreteCommand(Receiver receiver){
this.receiver =receiver;
}
@Override
public void execute(){
receiver.action();
}
}
//请求者
public class Invoker {
private Command command=null;
public Invoker(Command command){
this.command = command;
}
public void action(){
command.execute();
}
}
//接受者
public class Receiver {
public void action(){
System.out.println("执行操作");
}
}
public class Demo {
public static void main(String[] args){
Receiver receiver=new Receiver();
Command command = new ConcreteCommand(receiver);
Invoker invoker = new Invoker(command);
invoker.action();
}
}
分析:Demo里面,调用者将命令传进入,然后执行Action动作。由Command的receiver来执行相应的操作。这种模式可以让我们分离开命令行里面的If else判断。在我们需要自己去定义一些命令的时候,这种实现方式非常有效。
public class Memento {
private String state;
public Memento(String state){
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
public class Originator {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento saveStateToMemento(){
return new Memento(state);
}
public void getStateFromMemento(Memento memento){
this.state = memento.getState();
}
}
public class CareTaker {
public Stack mementos = new Stack<>();
public void add(Memento memento){
this.mementos.push(memento);
}
public Memento repeal(){
return mementos.pop();
}
}
public class Demo {
public static void main(String[] args){
Originator originator =new Originator();
CareTaker careTaker = new CareTaker();
originator.setState("第一次操作");
careTaker.add(originator.saveStateToMemento());
originator.setState("第二次操作");
careTaker.add(originator.saveStateToMemento());
originator.setState("第三次操作");
careTaker.add(originator.saveStateToMemento());
originator.getStateFromMemento(careTaker.repeal());
System.out.println(originator.getState());
originator.getStateFromMemento(careTaker.repeal());
System.out.println(originator.getState());
originator.getStateFromMemento(careTaker.repeal());
System.out.println(originator.getState());
}
}
//输出
第三次操作
第二次操作
第一次操作
public class Context {
private State state;
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void enchashment(){
state.enchashment();
}
}
public interface State {
public void enchashment();
}
public class LegalState implements State{
@Override
public void enchashment() {
System.out.println("我是合法账号,取钱没问题");
}
}
public class OverdraftState implements State{
@Override
public void enchashment() {
System.out.println("我是透支账号,无法取现");
}
}
public class Demo {
public static void main(String[] args){
Context context =new Context();
context.setState(new LegalState());
context.enchashment();
context.setState(new OverdraftState());
context.enchashment();
}
}
public interface ComputerPart {
public void accept(ComputerPartVisitor computerPartVisitor);
}
public class Computer implements ComputerPart{
ComputerPart[] parts;
public Computer(){
parts = new ComputerPart[]{
new Mouse(),
new Keyboard(),
new Monitor()
};
}
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
for(int i=0;i< parts.length;i++){
parts[i].accept(computerPartVisitor);
}
computerPartVisitor.visit(this);
}
}
public class ComputerPartDisplayVisitor implements ComputerPartVisitor{
@Override
public void visit(Computer computer) {
System.out.println("Display computer");
}
@Override
public void visit(Mouse mouse) {
System.out.println("Display mouse");
}
@Override
public void visit(Keyboard keyboard) {
System.out.println("Display keyboard");
}
@Override
public void visit(Monitor monitor) {
System.out.println("Display monitor");
}
}
public interface ComputerPartVisitor {
public void visit(Computer computer);
public void visit(Mouse mouse);
public void visit(Keyboard keyboard);
public void visit(Monitor monitor);
}
public class Keyboard implements ComputerPart{
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Monitor implements ComputerPart{
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Mouse implements ComputerPart{
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Demo {
public static void main(String[] args){
ComputerPart computer=new Computer();
computer.accept(new ComputerPartDisplayVisitor());
}
}
public interface Expression {
public boolean interpret(String context);
}
public class AndExpression implements Expression{
private Expression left;
private Expression right;
public AndExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public boolean interpret(String context) {
return left.interpret(context)&&right.interpret(context);
}
}
public class OrExpression implements Expression{
private Expression left;
private Expression right;
public OrExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public boolean interpret(String context) {
return left.interpret(context)||right.interpret(context);
}
}
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;
}
}
package com.opensource.jiangbiao.behavior.interpreter;
public class Demo {
public static Expression getMale(){
Expression jiangbiao = new TerminalExpression("jiangbiao");
Expression zhangshan = new TerminalExpression("zhangshan");
return new OrExpression(jiangbiao,zhangshan);
}
public static Expression getMarriedWomen(){
Expression wangmeimei = new TerminalExpression("wangmeimei");
Expression married =new TerminalExpression("married");
return new AndExpression(wangmeimei,married);
}
public static void main(String[] args){
Expression male = getMale();
System.out.println("jiangbiao is a male: "+male.interpret("jiangbiao"));
Expression marriedFemale = getMarriedWomen();
System.out.println("Wangmeimei is a married woman :"+getMarriedWomen().interpret("married wangmeimei"));
}
}
分析:解释器模式是用来对语法进行分析。比如(A&&B||C&&B)这种语法数是可以很好的用解释器模式来进行过滤分析的。