设计模式之管道模式——pipeline与valve

场景

在一个比较复杂的大型系统中,假如存在某个对象或数据流需要被进行繁杂的逻辑处理的话,我们可以选择在一个大的组件中进行这些繁杂的逻辑处理,这种方式确实达到了目的,但却是简单粗暴的。或许在某些情况这种简单粗暴的方式将带来一些麻烦,例如我要改动其中某部分处理逻辑、我要添加一些处理逻辑到流程、我要在流程中减少一些处理逻辑时,这里有些看似简单的改动都让我们无从下手,除了对整个组件进行改动。整个系统看起来没有任何可扩展性和可重用性。

是否有一种模式可以将整个处理流程进行详细划分,划分出的每个小模块互相独立且各自负责一段逻辑处理,这些逻辑处理小模块根据顺序连起来,前以模块的输出作为后一模块的输入,最后一个模块的输出为最终的处理结果。如此一来修改逻辑时只针对某个模块修改,添加或减少处理逻辑也可细化到某个模块颗粒度,并且每个模块可重复利用,可重用性大大增强。这种模式就是此章节要进行讨论的管道模式。

顾名思义,管道模式就像一条管道把多个对象连接起来,整体看起来就像若干个阀门嵌套在管道中,而处理逻辑就放在阀门上,如下图,需要处理的对象进入管道后,分别经过阀门一、阀门二、阀门三、阀门四,每个阀门都会对进入的对象进行一些逻辑处理,经过一层层的处理后从管道尾处理,此时的对象就是已完成处理的目标对象。
在这里插入图片描述

既然管道模式这么有用,我们希望能在程序中适当地考虑使用,为了实现此模式需要多个对象协作,可Valve接口定义了阀门的调用方法,由于阀门与阀门使用单链表结构连接所以需提供对next的操作,实现一个阀门对其进行扩展即可;Pipeline接口定义了管道操作阀门的方法,包括获取第一个阀门、获取基础阀门、添加阀门等方法,管道需对其扩展。

例子:

Valve接口

public interface Valve {
    public Valve getNext();
    public void setNext(Valve valve);
    public void invoke(String handling);
}

Pipeline 接口

public interface Pipeline {
    public Valve getFirst();
    public Valve getBasic();

    public void setBasic(Valve valve);
    public void addValve(Valve valve);
}

Valve 实现类 BasicValve

public class BasicValve implements Valve {
    protected Valve next = null;
    @Override
    public Valve getNext() {
        return next;
    }

    @Override
    public void invoke(String handling) {
        handling=handling.replaceAll("aa","bb");
        System.out.println("aa---bb基础阀门处理完后:" + handling);
    }

    @Override
    public void setNext(Valve valve) {
        this.next = valve;
    }
}

Valve 实现类 SecondValve

public class SecondValve implements Valve {
    protected Valve next = null;
    @Override
    public Valve getNext() {
        return next;
    }

    @Override
    public void invoke(String handling) {
        handling = handling.replaceAll("11","22");
        System.out.println("11----22  Second阀门处理完后:" + handling);
        getNext().invoke(handling);
    }

    @Override
    public void setNext(Valve valve) {
        this.next = valve;
    }
}

Valve 实现类 ThirdValve

public class ThirdValve implements Valve {
    protected Valve next = null;
    @Override
    public Valve getNext() {
        return next;
    }
    @Override
    public void invoke(String handling) {
        handling = handling.replaceAll("zz","yy");
        System.out.println("zz------yy  Third阀门处理完后:" + handling);
        getNext().invoke(handling);
    }
    @Override
    public void setNext(Valve valve) {
        this.next = valve;
    }
}

Valve 实现类 FourValve

public class FourValve implements Valve {
    protected Valve next = null;
    @Override
    public Valve getNext() {
        return next;
    }
    @Override
    public void invoke(String handling) {
        handling = handling.replaceAll("2222","1111");
        System.out.println("2222------1111  Four阀门处理完后:" + handling);
        getNext().invoke(handling);
    }
    @Override
    public void setNext(Valve valve) {
        this.next = valve;
    }
}

Pipeline 实现类 StandardPipeline

public class StandardPipeline implements Pipeline {
    protected Valve first = null;
    protected Valve basic = null;

    @Override
    public Valve getBasic() {
        return basic;
    }

    @Override
    public Valve getFirst() {
        return first;
    }

    @Override
    public void addValve(Valve valve) {
        if (first == null) {
            first = valve;
            valve.setNext(basic);
        } else {
            Valve current = first;
            while (current != null) {
                if (current.getNext() == basic) {
                    current.setNext(valve);
                    valve.setNext(basic);
                    break;
                }
                current = current.getNext();
            }
        }
    }

    @Override
    public void setBasic(Valve valve) {
        this.basic = valve;
    }
}

测试:

public class Main {
    public static void main(String[] args) {
        String handling="aabb1122zzyy";
        StandardPipeline pipeline = new StandardPipeline();
        BasicValve basicValve = new BasicValve();
        SecondValve secondValve = new SecondValve();
        ThirdValve thirdValve = new ThirdValve();
        FourValve fourValve = new FourValve();
        pipeline.setBasic(basicValve);
        pipeline.addValve(secondValve);
        pipeline.addValve(thirdValve);
        pipeline.addValve(fourValve);

        pipeline.getFirst().invoke(handling);
    }
}

结果,BasicValve是最后才执行得。

11----22  Second阀门处理完后:aabb2222zzyy
zz------yy  Third阀门处理完后:aabb2222yyyy
2222------1111  Four阀门处理完后:aabb1111yyyy
aa---bb基础阀门处理完后:bbbb1111yyyy

简单画了一个关联草图,Second->Third->Four->Basic顺序执行
在这里插入图片描述

管道模式,在管道中连接一个或多个阀门,每个阀门负责一部分逻辑处理,数据按规定的顺序往下流。此模式分解了逻辑处理任务,可方便对某任务单元进行安装拆卸,提高了流程的可扩展性、可重用性、机动性、灵活性。

Pipeline 设计模式是一种将一个大型任务分解成多个小任务并将它们串联起来的设计模式。每个小任务都会处理一部分数据并将其传递给下一个任务,直到最终结果被生成。这种模式可以提高代码的可读性和可维护性,同时也可以提高代码的性能。 下面是一个简单的 Pipeline 设计模式的示例: ```java import java.util.ArrayList; import java.util.List; public class PipelineDemo { public static void main(String[] args) { List<String> input = new ArrayList<>(); input.add("apple"); input.add("banana"); input.add("cherry"); Pipeline<String, Integer> pipeline = new Pipeline<>(); pipeline.add(new StringLengthTask()) .add(new SquareTask()); List<Integer> output = pipeline.execute(input); System.out.println(output); } } interface Task<I, O> { O execute(I input); } class Pipeline<I, O> { private List<Task<?, ?>> tasks = new ArrayList<>(); public <T> Pipeline<I, T> add(Task<O, T> task) { tasks.add(task); return (Pipeline<I, T>) this; } public List<O> execute(List<I> input) { List<O> output = new ArrayList<>(); for (I i : input) { Object result = i; for (Task<?, ?> task : tasks) { result = task.execute(result); } output.add((O) result); } return output; } } class StringLengthTask implements Task<String, Integer> { @Override public Integer execute(String input) { return input.length(); } } class SquareTask implements Task<Integer, Integer> { @Override public Integer execute(Integer input) { return input * input; } } ``` 在这个示例中,我们定义了一个 Pipeline 类,它包含了一个任务列表。我们可以通过调用 add 方法来添加任务。execute 方法接受一个输入列表,并依次将每个输入传递给任务列表中的每个任务。最终结果被收集到一个输出列表中并返回。 在这个示例中,我们定义了两个任务:StringLengthTask 和 SquareTask。StringLengthTask 接受一个字符串并返回其长度,SquareTask 接受一个整数并返回其平方。我们将这两个任务添加到 Pipeline 中,并将一个字符串列表传递给 execute 方法。最终,我们得到了一个整数列表,其中包含了每个字符串的长度的平方。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值