设计模式大类--行为模式(下)
七、Strategy(策略模式)
描述:定义了一系列的算法,将每一种算法封装起来并可以相互替换使用,策略模式让算法独立于使用它的客户应用而独立变化。
优点:各个部分之间是弱连接 的关系,弱连接的特性使软件具有更强的可扩展性 ,易于维护 ;更重要的是,它大大提高了软件可重用性 。
例子:
举例(TreeSet 、TreeMap就是很好的例子 )
public class Test {
/*客户端*/
public static void main(String[] args) {
//面向接口
Strategy addStrategy = new AddStrategy();
Strategy subtractStrategy = new SubtractStrategy();
Environment envi = new Environment(addStrategy);
System.out.println(envi.calculate(5, 2));
//策略的互换
envi.setStrategy(subtractStrategy);
System.out.println(envi.calculate(5, 2));
}
}
/*
* 抽象策略角色
* */
interface Strategy{
public int calculate(int a,int b);
}
/*
* 具体策略角色,实现加法
* */
class AddStrategy implements Strategy{
@Override
public int calculate(int a, int b) {
return a+b;
}
}
/*
* 具体策略角色,实现减法
* */
class SubtractStrategy implements Strategy{
@Override
public int calculate(int a, int b) {
return a-b;
}
}
/*
* 环境角色
* */
class Environment{
private Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public Environment(Strategy strategy){
this.strategy = strategy;
}
public int calculate(int a,int b){
return strategy.calculate(a, b);
}
}
八、Mediator(中介者)
描述:用一个中介对象来封装一系列关于对象交互行为
优点:避免过度耦合,将一对多的关系简化为一对一的关系
举例:
有两个类A和B,类中各有一个数字,并且要保证类B中的数字永远是类A中数字的100倍。也就是说,当修改类A的数时,将这个数字乘以100赋给类B,而修改类B时,要将数除以100赋给类A。类A类B互相影响,就称为同事类。
abstract class AbstractColleague {
protected int number;
public int getNumber() {
return number;
}
public void setNumber(int number){
this.number = number;
}
//注意这里的参数不再是同事类,而是一个中介者
public abstract void setNumber(int number, AbstractMediator am);
}
class ColleagueA extends AbstractColleague{
public void setNumber(int number, AbstractMediator am) {
this.number = number;
am.AaffectB();
}
}
class ColleagueB extends AbstractColleague{
@Override
public void setNumber(int number, AbstractMediator am) {
this.number = number;
am.BaffectA();
}
}
abstract class AbstractMediator {
protected AbstractColleague A;
protected AbstractColleague B;
public AbstractMediator(AbstractColleague a, AbstractColleague b) {
A = a;
B = b;
}
public abstract void AaffectB();
public abstract void BaffectA();
}
class Mediator extends AbstractMediator {
public Mediator(AbstractColleague a, AbstractColleague b) {
super(a, b);
}
//处理A对B的影响
public void AaffectB() {
int number = A.getNumber();
B.setNumber(number*100);
}
//处理B对A的影响
public void BaffectA() {
int number = B.getNumber();
A.setNumber(number/100);
}
}
public class Client {
public static void main(String[] args){
AbstractColleague collA = new ColleagueA();
AbstractColleague collB = new ColleagueB();
AbstractMediator am = new Mediator(collA, collB);
System.out.println("==========通过设置A影响B==========");
collA.setNumber(1000, am);
System.out.println("collA的number值为:"+collA.getNumber());
System.out.println("collB的number值为A的100倍:"+collB.getNumber());
System.out.println("==========通过设置B影响A==========");
collB.setNumber(1000, am);
System.out.println("collB的number值为:"+collB.getNumber());
System.out.println("collA的number值为B的0.01倍:"+collA.getNumber());
}
}
九、Interpreter(解释器)
描述:定义语言的文法 ,并且建立一个解释器来解释该语言中的句子
优点:是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了
例子:
为了帮助大家理解Interpreter模式的基本概念,我们在这里只举一个最简单的例子。
让一个表达式a经过PlusExpression解释器处理后使该表达式+1,经过MinusExpression解释器处理后使该表达式-1。
public class Client {
public static void main(String []args) {
String inputExpr = "10";
Context context = new Context(inputExpr);
List list = new ArrayList();
list.add(new PlusExpression());
list.add(new PlusExpression());
list.add(new MinusExpression());
list.add(new MinusExpression());
list.add(new MinusExpression());
for (int i=0;i<list.size();i++) {
AbstractExpression expression = (AbstractExpression)list.get(i);
expression.interpret(context);
}
System.out.println(context.getOutput());
}
}
/**
* Context
*
*/
class Context {
private String input;
private int output;
public Context (String input) {
this. input = input;
}
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public int getOutput() {
return output;
}
public void setOutput(int output) {
this.output = output;
}
}
/**
* Expression & subclass
*
*/
abstract class AbstractExpression {
public abstract void interpret(Context context);
}
class PlusExpression extends AbstractExpression {
public void interpret(Context context) {
System.out.println("PlusExpression ++");
String input = context.getInput();
int parsedResult = Integer.parseInt(input);
parsedResult ++;
context.setInput(String.valueOf(parsedResult));
context.setOutput(parsedResult);
}
}
class MinusExpression extends AbstractExpression {
public void interpret(Context context) {
System.out.println("PlusExpression --");
String input = context.getInput();
int parsedResult = Integer.parseInt(input);
parsedResult --;
context.setInput(String.valueOf(parsedResult));
context.setOutput(parsedResult);
}
}
十、Visitor(访问者)
描述:作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作
优点:给原来类层次增加新操作,不必修改整个类层次,只需实现一个具体访问者
例子:
被访问者抽象类Node.java
abstract public class Node
{
public abstract void accept(Visitor visitor);
/** @link dependency */
/*# Visitor lnkVisitorA; */
}
被访问者实现类NodeA .java
public class NodeA extends Node
{
public void accept(Visitor visitor)
{
visitor.visit(this);
}
public String operationA()
{
return "NodeA is visited";
}
}
被访问者实现类NodeB .java
public class NodeB extends Node
{
public void accept(Visitor visitor)
{
visitor.visit(this);
}
public String operationB()
{
return "NodeB is visited";
}
}
访问者类Visitor.java
public class Visitor
{
public void visit(NodeA nodeA)
{
System.out.println( nodeA.operationA() );
}
public void visit(NodeB nodeB)
{
System.out.println( nodeB.operationB() );
}
}
增加与迭代被访问者类ObjectStructure.java
public class ObjectStructure
{
private Vector nodes;
/**
* @link aggregation
*/
private Node node;
public ObjectStructure()
{
nodes = new Vector();
}
public void action(Visitor visitor)
{
for(Enumeration e = nodes.elements();
e.hasMoreElements();)
{
node = (Node) e.nextElement();
node.accept(visitor);
}
}
public void add(Node node)
{
nodes.addElement(node);
}
}
客户端类Client.java
public class Client
{
private static ObjectStructure aObjects;
private static Visitor visitor;
static public void main(String[] args)
{
aObjects = new ObjectStructure();
aObjects.add(new NodeA());
aObjects.add(new NodeB());
visitor = new Visitor();
aObjects.action(visitor);
}
}