设计模式(五):初识设计模式

101 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第6天,点击查看活动详情

上一篇文章介绍了设计模式的结构型模式,感兴趣的同学请移步设计模式(四):初识设计模式

行为型模式

责任链模式(Chain of Responsibility Pattern)

责任链模式又叫职责链模式,它为请求创建了一个接受者对象的链,当一个对象不能处理该请求,那么它会把相同的请求传给下一个接受者,依此类推。

责任链模式的角色及职责

Handler:抽象的处理者,定义了一个处理请求的接口,同时含另外的Handler。

ConcreteHandlerA,B:具体的处理者,处理它自己负责的请求,可以访问后继者即下一个处理者,如果可以处理当前请求则进行处理,否则交给后继者处理,从而形成一个责任链。

Request:表示一个请求。

代码演示:

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);
}

优点将请求和处理分开,实现解耦,提高系统的灵活性,简化了对象,使对象不需要知道链的结构。

缺点性能会受到影响,特别是链较长时需要控制节点数量。

命令模式(Command Pattern)

命令模式将一个请求封装为一个对象,以便使用不同参数来表示。

命名模式的角色及职责:

Invoker:调用者角色。

Command:命令角色,需要执行的所有命令都在这里,可以是接口或抽象类。

Receiver:接受者角色,知道如何实施和执行一个请求相关的操作。

ConcreteCommand:将一个接受者与一个动作绑定,调用接受者相应的操作。

代码演示:

//命令接口
public interface Order {
    void execute();
}

//请求类
public class Stock {

    private String name = "ABC";
    private int quantity = 10;

    public void buy(){
        System.out.println("Stock [ Name: "+name+", 
                Quantity: " + quantity +" ] bought");
    }
    public void sell(){
        System.out.println("Stock [ Name: "+name+", 
                Quantity: " + quantity +" ] sold");
    }
}

//实体类
public class BuyStock implements Order {
    private Stock abcStock;

    public BuyStock(Stock abcStock){
        this.abcStock = abcStock;
    }

    public void execute() {
        abcStock.buy();
    }
}

public class SellStock implements Order {
    private Stock abcStock;

    public SellStock(Stock abcStock){
        this.abcStock = abcStock;
    }

    public void execute() {
        abcStock.sell();
    }
}

//命令调用类
public class Broker {
    private List<Order> orderList = new ArrayList<Order>();

    public void takeOrder(Order order){
        orderList.add(order);
    }

    public void placeOrders(){
        for (Order order : orderList) {
            order.execute();
        }
        orderList.clear();
    }
}

优点将发起请求的对象与执行请求的对象解耦,降低了系统的耦合度

缺点可能导致某些系统有过多的具体命令类

解释器模式(Interpreter Pattern)

解释器模式是给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)。编译器、正则表达式都可以看做解释器。

解释器模式的角色及职责

Context:环境角色,含有除解释器之外的全局信息。

AbstractExpression:抽象表达式,声明一个抽象的解释操作,这个方法为抽象语法树中所有节点所共享。

TerminalExpression:终结符表达式,实现与文法中的终结符相关的解释操作。

NonTerminalExpression:非终结符表达式,为文法中的非终结实现解释操作。

代码演示:

//表达式接口
public interface Expression {
    public boolean interpret(String 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;
    }
}
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);
    }
}

优点程序有良好的扩展性。

缺点解释器模式会引起类膨胀,采用递归调用方法会导致调试复杂,效率低。

迭代器模式(Iterator Pattern)

迭代器模式提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示。

迭代器模式的角色及职责

Iterator:迭代器接口,是系统提供。

ConcreteIterator:具体的迭代器类,管理迭代。

Aggregate:统一的聚合接口,将客户端和具体聚合解耦。

ConcreteAggreage:具体的聚合持有对象集合,并提供一个方法,返回一个迭代器。

代码演示:

//创建接口
public interface Iterator {
    public boolean hasNext();
    public Object next();
}

public interface Container {
    public Iterator getIterator();
}

//创建实现了Container接口的实体类
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 < names.length){
                return true;
            }
            return false;
        }

        @Override
        public Object next() {
            if(this.hasNext()){
                return names[index++];
            }
            return null;
        }
    }
}

优点提供了一个统一的方法遍历对象,隐藏了聚合的内部结构。

缺点每个聚合对象都要一个迭代器,会生成多个迭代器不好管理类。

中介者模式(Mediator Pattern)

中介者模式用一个中介对象来封装一系列的对象交互,使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

中介者模式的角色及职责:

Mediator:抽象中介者,定义了同事对象到中介者对象的接口。

Colleague:抽象同事类。

ConcreteMediator:具体的中介者对象,实现抽象方法,他需要知道所有的具体的同事类,即以一个集合来管理HashMap,并接受某个同事对象消息,完成相应任务。

ConcreteColleague:具体的同事类,每个同事只知道自己的行为,而不了解其他同事的行为,他们都依赖中介者对象。

代码演示:

//中介者对象
public class ChatRoom {
    public static void showMessage(User user, String message){
        System.out.println(user.getName+message);
    }
}

//同事类
public class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public User(String name){
        this.name  = name;
    }

    public void sendMessage(String message){
        ChatRoom.showMessage(this,message);
    }
}

优点减少类间耦合,符合迪米特法则。

缺点中介者承担了较多的责任,一旦中介者出现了问题,整个系统都会受到影响。

如有不对的地方,欢迎大家指正。