行为型设计模式:
在行为型设计模式,分为4类:
1类:通过父类与子类的关系进行实现。
2类:两个独立类之间
3类:类的状态
4类:通过中间类
1】策略模式(Strategy)
策略模式定义了一系列的算法,并且将每个算法都封装起来,使得他们可以相互替换,且算法的变化不会影响到使用算法的客户。
需要设计的一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计抽象类用来提供辅助函数。
package com.mjf.model.strategy;
public interface ICalculator {
int calculate(String exp);
}
package com.mjf.model.strategy;
public class AbstractCalculator {
public int[] split(String exp,String opt){
String array[] = exp.split(opt);
int arrayInt[] = new int[2];
arrayInt[0] = Integer.parseInt(array[0]);
arrayInt[1] = Integer.parseInt(array[1]);
return arrayInt;
}
}
package com.mjf.model.strategy;
public class Multiply extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp, "\\*");
return arrayInt[0]*arrayInt[1];
}
}
package com.mjf.model.strategy;
public class Minus extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp, "-");
return arrayInt[0]-arrayInt[1];
}
}
package com.mjf.model.strategy;
public class Plus extends AbstractCalculator implements ICalculator {
@Override
public int calculate(String exp) {
int arrayInt[] = split(exp, "\\+");
return arrayInt[0]+arrayInt[1];
}
}
/ ** 测试类 */
package com.mjf.test.strategy;
import com.mjf.model.strategy.ICalculator;
import com.mjf.model.strategy.Minus;
import com.mjf.model.strategy.Multiply;
import com.mjf.model.strategy.Plus;
public class CalculatorTest {
public static void main(String[] args) {
//String exp = "2+8";
//ICalculator cal = new Plus();
//String exp = "8-2";
//ICalculator cal = new Minus();
String exp = "2*8";
ICalculator cal = new Multiply();
int result = cal.calculate(exp);
System.out.println(result);
}
}
策略模式的决定权在用户端这边,系统本身提供的是不同算法的实现,新增或者删除算法,对各种算法做了封装。
所以,策略模式多是用在算法决策系统中,主导权在外部用户的情况。
2】模板方法模式(Template Method)
模板方法模式,指的是一个抽象类中,有一个主方法,再定义1...n个方法。可以是抽象的,也可以是实际的方法,定义一个类,继承该抽象类,重写抽象方法,通过调用抽象类,实现对子类的调用。
package com.mjf.model.template_method;
public abstract class AbstractCalculator {
/*主方法,实现对本类其它方法的调用*/
public final int calculate(String exp,String opt){
int array[] = split(exp,opt);
return calculate(array[0],array[1]);
}
/*被子类重写的方法*/
abstract public int calculate(int num1,int num2);
public int[] split(String exp,String opt){
String array[] = exp.split(opt);
int arrayInt[] = new int[2];
arrayInt[0] = Integer.parseInt(array[0]);
arrayInt[1] = Integer.parseInt(array[1]);
return arrayInt;
}
}
package com.mjf.model.template_method;
public class Plus extends AbstractCalculator {
@Override
public int calculate(int num1, int num2) {
// TODO Auto-generated method stub
return num1 + num2;
}
}
/** 测试类 */
package com.mjf.test.template_method;
import com.mjf.model.template_method.AbstractCalculator;
import com.mjf.model.template_method.Plus;
public class TemplateTest {
public static void main(String[] args) {
String exp = "2+8";
AbstractCalculator cal = new Plus();
int result = cal.calculate(exp, "\\+");
System.out.println(result);
}
}
3】观察者模式(Observer)
观察者模式类似于邮件订阅和Rss订阅相关功能。即是:当一个对象变化时,其他依赖该对象的对象都会收到通知,并且会随着变化!对象之间是一种一对多的关系。
MySubject类是我们的主对象,Observer1和Observer2是依赖于MySubject的对象,当MySubject变化时,Observer1和Observer2也会变化。AbstractSubject类中定义需要监控的对象列表,可以对其进行修改:增加或者删除被监控对象,并且MySubject变化的时候,负责通知在列表内存的对象。
package com.mjf.model.observer;
public interface Observer {
void update();
}
package com.mjf.model.observer;
public class Observer1 implements Observer {
@Override
public void update() {
// TODO Auto-generated method stub
System.out.println("this is observer1");
}
}
package com.mjf.model.observer;
public class Observer2 implements Observer {
@Override
public void update() {
// TODO Auto-generated method stub
System.out.println("this is observer2");
}
}
package com.mjf.model.observer;
public interface Subject {
/** 添加观察者 */
void add(Observer observer);
/** 删除观察者 */
void del(Observer observer);
/** 通知观察对象 */
void notifyObservers();
void operation();
}
package com.mjf.model.observer;
public class MySubject extends AbstractSubject {
@Override
public void operation() {
// TODO Auto-generated method stub
System.out.println("update self");
notifyObservers();
}
}
package com.mjf.model.observer;
import java.util.Enumeration;
import java.util.Vector;
public abstract class AbstractSubject implements Subject {
private Vector<Observer> vector = new Vector<Observer>();
@Override
public void add(Observer observer) {
vector.add(observer);
}
@Override
public void del(Observer observer) {
vector.remove(observer);
}
@Override
public void notifyObservers() {
Enumeration<Observer> enumo = vector.elements();
while(enumo.hasMoreElements()){
enumo.nextElement().update();
}
}
}
/** 测试类 */
package com.mjf.test.observer;
import com.mjf.model.observer.MySubject;
import com.mjf.model.observer.Observer1;
import com.mjf.model.observer.Observer2;
import com.mjf.model.observer.Subject;
public class ObserverTest {
public static void main(String[] args) {
Subject sub = new MySubject();
sub.add(new Observer1());
sub.add(new Observer2());
sub.operation();
}
}
4】迭代子模式(Iterator)
迭代器模式是顺序访问聚集中的对象,类似于集合类。在迭代器模式中:一是需要遍历的对象,即是聚集对象;二是迭代器对象,用于对聚集对象进行遍历访问。
package com.mjf.model.iterator;
public interface Iterator {
//前移
Object previous();
Object next();
boolean hasnext();
Object first();
}
package com.mjf.model.iterator;
public interface Collection {
Iterator iterator();
Object get(int i);
int size();
}
package com.mjf.model.iterator;
public class MyCollection implements Collection {
public String string[] ={"A","B","C","D","E"};
@Override
public Iterator iterator() {
// TODO Auto-generated method stub
return new MyIterator(this);
}
@Override
public Object get(int i) {
// TODO Auto-generated method stub
return string[i];
}
@Override
public int size() {
// TODO Auto-generated method stub
return string.length;
}
}
package com.mjf.model.iterator;
public class MyIterator implements Iterator {
private Collection collection;
private int pos = -1;
public MyIterator(Collection collection){
this.collection = collection;
}
@Override
public Object previous() {
if(pos > 0){
pos--;
}
return collection.get(pos);
}
@Override
public Object next() {
if(pos<collection.size()-1){
pos++;
}
return collection.get(pos);
}
@Override
public boolean hasnext() {
if(pos<collection.size()-1){
return true;
}else{
return false;
}
}
@Override
public Object first() {
pos = 0;
return collection.get(pos);
}
}
/** 测试类 */
package com.mjf.test.iterator;
import com.mjf.model.iterator.Collection;
import com.mjf.model.iterator.Iterator;
import com.mjf.model.iterator.MyCollection;
public class IteratorTest {
public static void main(String[] args) {
Collection collection = new MyCollection();
Iterator it = collection.iterator();
while(it.hasnext()){
System.out.println(it.next());
}
}
}
5】责任链模式(Chain of Responsibility)
责任链模式,即是有多个的对象,每个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。但是不知道是哪个对象会去处理该请求。而责任链模式就可以对系统进行动态的调整。
package com.mjf.model.chain_of_responsibility;
public interface Handler {
void operator();
}
package com.mjf.model.chain_of_responsibility;
public abstract class AbstractHandler {
private Handler handler;
public Handler getHandler() {
return handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
}
package com.mjf.model.chain_of_responsibility;
public class MyHandler extends AbstractHandler implements Handler {
private String name;
public MyHandler(String name) {
this.name = name;
}
@Override
public void operator() {
System.out.println(name+"deal!");
if(getHandler()!=null){
getHandler().operator();
}
}
}
/** 测试类 */
package com.mjf.test.chain_of_responsibility;
import com.mjf.model.chain_of_responsibility.MyHandler;
public class ChainTest {
public static void main(String[] args) {
MyHandler h1 = new MyHandler("h1");
MyHandler h2 = new MyHandler("h2");
MyHandler h3 = new MyHandler("h3");
h1.setHandler(h2);
h2.setHandler(h3);
h1.operator();
}
}
在责任链上的请求可以是一天链,可以是一个树,也可以是一个环,模式本身不约束这个,需要我们自己的去实现。同时,在一个时刻,命令只允许由一个对象传到他的下一个对象,而不允许传给多个对象。
6】命令模式(Command)
命令模式可以相当于理解为:一个司令去命令一个士兵完成一件事情,从整个事情的角度来说,司令的作用是,发出命令;而命令经过传递,传到了士兵的耳朵里,士兵去执行。
而这三者是相互解耦的,任何的一方都不用去依赖其他人,只需要做好自己的分内事即可,而司令只需要的是一个结果,不会在乎士兵是怎么样去实现的。
package com.mjf.model.command;
public interface Command {
void exe();
}
package com.mjf.model.command;
public class Receiver {
public void action(){
System.out.println("command Receiver");
}
}
package com.mjf.model.command;
public class MyCommand implements Command {
private Receiver receiver;
public MyCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void exe() {
// TODO Auto-generated method stub
receiver.action();
}
}
package com.mjf.model.command;
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void action(){
command.exe();
}
}
/** 测试类 */
package com.mjf.test.command;
import com.mjf.model.command.Command;
import com.mjf.model.command.Invoker;
import com.mjf.model.command.MyCommand;
import com.mjf.model.command.Receiver;
public class CommandTest {
public static void main(String[] args) {
Receiver receiver = new Receiver();
Command cmd = new MyCommand(receiver);
Invoker invoker = new Invoker(cmd);
invoker.action();
}
}
命令模式的目的是达到命令的发出者和执行者之间解耦,实现请求和执行的分开。如Struts的开发模式。
7】备忘录模式(Memento)
主要的目的是保存一个对象的某个状态,以便在适当的时候恢复对象。简单的说是:有个原始类A,A中有各种属性,A可以决定需要备份的属性,备忘录B是用来存储A的一些内部状态,而类C,是一个用来存储备忘录的,只是用来存储,但是不能修改。
package com.mjf.model.memento;
public class Original {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Original(String value) {
this.value = value;
}
public Memento createMemento(){
return new Memento(value);
}
public void restoreMemento(Memento memento){
this.value = memento.getValue();
}
}
package com.mjf.model.memento;
public class Memento {
private String value;
public Memento(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package com.mjf.model.memento;
public class Storage {
private Memento memento;
public Storage(Memento memento) {
this.memento = memento;
}
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
/** 测试类 */
package com.mjf.test.memento;
import com.mjf.model.memento.Original;
import com.mjf.model.memento.Storage;
public class MementoTest {
public static void main(String[] args) {
// 创建原始类
Original origi = new Original("egg");
// 创建备忘录
Storage storage = new Storage(origi.createMemento());
// 修改原始类的状态
System.out.println("初始化状态为:" + origi.getValue());
origi.setValue("niu");
System.out.println("修改后的状态为:" + origi.getValue());
// 回复原始类的状态
origi.restoreMemento(storage.getMemento());
System.out.println("恢复后的状态为:" + origi.getValue());
}
}
关键就是在于创建了一个中间的备忘录类来存储备忘的属性,其实这应该算是“备份-恢复”模式比较符合。
8】状态模式(State)
状态模式的思想为:当对象的状态改变的时候,同时会改变其行为。如:QQ,不同的状态:在线、隐身、忙碌等,每个状态对应了不同的操作。
状态模式的特点为:可以通过改变状态来获得不同的行为。外部可以看到你的变化。
package com.mjf.model.state;
public class State {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void method1(){
System.out.println("execute the first opt!");
}
public void method2(){
System.out.println("execute the second opt!");
}
}
package com.mjf.model.state;
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void method() {
if (state.getValue().equals("state1")) {
state.method1();
} else if (state.getValue().equals("state2")) {
state.method2();
}
}
}
/** 测试类 */
package com.mjf.test.state;
import com.mjf.model.state.Context;
import com.mjf.model.state.State;
public class StateTest {
public static void main(String[] args) {
State state = new State();
Context context = new Context(state);
state.setValue("state1");
context.method();
state.setValue("state2");
context.method();
}
}
在实际开发中,状态模式运用的比较多,可以根据对象的某一个属性,来区别开他们的不同功能,比如权限等。
9】访问者模式(Visitor)
访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。其缺点就是增加新的数据结构很困难。
简而言之,访问者模式是一种分离对象数据结构与行为的方法,通过这种分离,可以达到为一个被访问者动态添加新的操作而无需做其他的修改的效果。
package com.mjf.model.Visitor;
public interface visitor {
void visit(Subject sub);
}
package com.mjf.model.Visitor;
public interface Subject {
public void accept(visitor visitor);
public String getSubject();
}
package com.mjf.model.Visitor;
public class MySubject implements Subject {
@Override
public void accept(visitor visitor) {
visitor.visit(this);
}
@Override
public String getSubject() {
return "love";
}
}
package com.mjf.model.Visitor;
public class MyVisitor implements visitor {
@Override
public void visit(Subject sub) {
System.out.println("visit the subject:"+sub.getSubject());
}
}
/** 测试类 */
package com.mjf.test.visitor;
import com.mjf.model.Visitor.MySubject;
import com.mjf.model.Visitor.MyVisitor;
import com.mjf.model.Visitor.Subject;
import com.mjf.model.Visitor.visitor;
public class VisitorTest {
public static void main(String[] args) {
visitor visitor = new MyVisitor();
Subject sub = new MySubject();
sub.accept(visitor);
}
}
使用访问者模式,是在为一个现有的类增加新的功能。当考虑到:新功能可能与现有功能出现兼容性问题;以后可能会在添加新的功能;如果类不允许修改代码。
使用访问者模式,就可以很好的解决上述的问题,比较适用在数据结构相对稳定的系统,把数据结构和算法进行了解耦。
10】中介者模式(Mediator)
中介者模式实质也是降低类与类之间的耦合度的。当类类之间具有依赖关系的话,会不利于功能的拓展和维护,当需要修改一个对象时,其他关联的对象都得进行修改了。
User类统一接口,User1和User2分别是不同的对象,二者之间有关联,如果不采用中介者模式,则需要二者相互持有引用,这样二者的耦合度很高,为了解耦,引入了Mediator类,提供统一接口,MyMediator为其实现类,里面持有User1和User2的实例,用来实现对User1和User2的控制。这样User1和User2两个对象相互独立,他们只需要保持好和Mediator之间的关系就行,剩下的全由MyMediator类来维护。
package com.mjf.model.mediator;
public interface Mediator {
void createMediator();
void workAll();
}
package com.mjf.model.mediator;
public class MyMediator implements Mediator {
private User user1;
private User user2;
public User getUser1() {
return user1;
}
public User getUser2() {
return user2;
}
@Override
public void createMediator() {
// TODO Auto-generated method stub
user1 = new User1(this);
user2 = new User2(this);
}
@Override
public void workAll() {
// TODO Auto-generated method stub
user1.work();
user2.work();
}
}
package com.mjf.model.mediator;
public abstract class User {
private Mediator mediator;
public Mediator getMediator(){
return mediator;
}
public User(Mediator mediator) {
this.mediator = mediator;
}
public abstract void work();
}
package com.mjf.model.mediator;
public class User2 extends User {
public User2(Mediator mediator) {
super(mediator);
}
@Override
public void work() {
// TODO Auto-generated method stub
System.out.println("user2 exe!");
}
}
package com.mjf.model.mediator;
public class User1 extends User {
public User1(Mediator mediator) {
super(mediator);
}
@Override
public void work() {
// TODO Auto-generated method stub
System.out.println("user1 exe!");
}
}
/** 测试类 */
package com.mjf.test.mediator;
import com.mjf.model.mediator.Mediator;
import com.mjf.model.mediator.MyMediator;
public class MediatorTest {
public static void main(String[] args) {
Mediator mediator = new MyMediator();
mediator.createMediator();
mediator.workAll();
}
}
11】解释器模式(Interpreter)
解释器模式是一般在OOP开发中的编译器的开发中使用,适用的范围比较窄。
package com.mjf.model.interpreter;
public interface Expression {
int interpret(Context context);
}
package com.mjf.model.interpreter;
public class Context {
private int num1;
private int num2;
public Context(int num1, int num2) {
super();
this.num1 = num1;
this.num2 = num2;
}
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
}
package com.mjf.model.interpreter;
public class Plus implements Expression {
@Override
public int interpret(Context context) {
return context.getNum1() + context.getNum2();
}
}
package com.mjf.model.interpreter;
public class Minus implements Expression {
@Override
public int interpret(Context context) {
return context.getNum1() - context.getNum2();
}
}
/** 测试类 */
package com.mjf.test.Interpreter;
import com.mjf.model.interpreter.Context;
import com.mjf.model.interpreter.Minus;
import com.mjf.model.interpreter.Plus;
public class InterpreterTest {
public static void main(String[] args) {
// 计算9+2-8的值
int result = new Minus().interpret((new Context(new Plus()
.interpret(new Context(9, 2)), 8)));
System.out.println(result);
}
}
解释器模式主要适用于做各种解释器的使用,如解释正则表达式,解释转义等。
学习了设计模式的这些日子来说,相对简单的去理解的是创建型模式,而感觉不好理解的行为型设计模式,因为行为的设计模式有一些很容易与其他的模式混淆,这需要很好的去进行理解消化才行。