精华内容
下载资源
问答
  • 行为型模式

    2021-02-24 15:46:55
    行为型模式 行为型模式用于描述程序在运行时复杂的流程控制, 即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务, 它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象行为...

    行为型模式

    行为型模式用于描述程序在运行时复杂的流程控制,

    即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,

    它涉及算法与对象间职责的分配。



    行为型模式分为类行为模式和对象行为模式

    前者采用继承机制来在类间分派行为,

    后者采用组合或聚合在对象间分配行为。

    由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。



    行为型模式分为:

    • 模板方法模式

    • 策略模式

    • 命令模式

    • 职责链模式

    • 状态模式

    • 观察者模式

    • 中介者模式

    • 迭代器模式

    • 访问者模式

    • 备忘录模式

    • 解释器模式

    以上 11 种行为型模式,除了模板方法模式和解释器模式是类行为型模式,其他的全部属于对象行为型模式

     

    展开全文
  • 行为型模式(BehavioralPattern)是对在不同的对象之间划分责任和算法的抽象化。行为型模式不仅仅关注类和对象的结构,而且重点关注它们之间的相互作用。在系统运行时,对象并不是孤立的,它们可以通过相互通信与协作...
  • 设计模式之行为型模式

    热门讨论 2019-11-23 21:37:13
    开篇,向大家介绍一下行为型模式行为型模式涉及算法和对象间职责的分配。 行为型模式同样分为行为型类模式和行为型对象模式 行为型类模式使用继承机制在类间分配行为。 行为型对象模式使用对象复合而不是继承...

    开篇,向大家介绍一下行为型模式。

    行为型模式涉及算法和对象间职责的分配。

    行为型模式同样分为行为型类模式和行为型对象模式

    行为型类模式使用继承机制在类间分配行为。

    行为型对象模式使用对象复合而不是继承。

    一些行为对象模式描述了一组对等的对象怎样相互协作以完成其中任一个对象都无法单独完成的任务。

    eg:mediator、chain of responsibility,observer

    其他行为型对象模式常将行为封装在一个对象中并将请求指派给它。

    eg:strategy,state,command,visitor,iterator。

    行为型设计模式共包括以下几个模式:

    • 观察者模式
    • 命令模式
    • 职责链模式
    • 状态模式
    • 策略模式
    • 解释器模式
    • 访问者模式
    • 中介者模式
    • 迭代器模式
    • 备忘录模式
    • 模块方法模式

    接下来我们详细的学习一下各个模式:

    观察者模式(Observer)

    内容:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

    特点:

    1、使用该模式的目的:

    将一个系统分割成一系列相互协作的类有个副作用,就是需要维护相关对象的一致性。这就会产生高耦合,故而使用该模式进行解耦合。让耦合双方都依赖于抽象,而不是依赖于具体。从而使各自的变化都不会影响另一边的变化。

    2、何时使用该模式:

    当一个对象的改变需要同时改变其他对象时;而且它不知道具体有多少对象有待改变。

    当一个抽象模式有两个方面,其中一个方面依赖于另一方面,通过观察者,可以将两者封装在独立的对象中使它们各自独立变化

    不足:

    该模式还是存在抽象通知者依赖抽象观察者的情况,故而如果没有这个接口,就无法实现了。而且调用方法单一,只有一个更新,如果有其他需求是无法实现的。

    结构图:

     命令模式(Command)

    内容:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

    作用:

    1、能比较容易的设计一个命令队列。

    2、在需要的情况下,可以比较容易地将命令记入日志

    3、允许接收请求的一方决定是否要否决请求

    4、可以容易地实现对请求的撤销和重做。

    5、由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。

    6、命令模式把一个操作的对象与知道怎么执行一个操作的对象分割开。

    结构图:

     

    职责链模式(Chain of Responsibility)

    内容:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

    优点:

    接收者与发送者无需明确对方信息,链中的对象自己也不知道链结构,如此可简化对象的相互连接,他们仅需一个指向其后继结点的引用,而不需保持它所有的候选接受者的引用。

    可以随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性。

    要注意一个请求极有可能到了链的末端都得不到处理,或者因为没有正确的配置而得不到处理。

    结构图:

     

    状态模式(State)

    内容:

    当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

    优点:

    ① 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。目的:消除庞大的条件分支语句

    即:将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在与某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换。

    ② 通过把各种状态转移逻辑分布到State的子类中。目的:减少相互间的依赖。

    应用:

    当一个对象的行为取决于它的状态,并且他必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式。

    结构图:

    策略模式

    内容:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

    优点:

    ① 策略是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合

    ②策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。

    ③简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。

    ④当不同的行为堆砌在一个类中,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的Strategy类中,可以在使用这些行为的类中消除条件语句。

    应用:

    策略模式就是用来封装算法的,但在实际中,我们可以用它来封装任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

    缺点:

    在基本策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。任何需求都需要需求成本。需求改动比较多。

    结构图:

     

    解释器模式(Interpreter)

    内容:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

    应用:如果一种特定类型的问题发生的频率足够高,就可能值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决这个问题。

    当一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可用解释器模式。

    优点:

    容易地改变和扩展文法,因为该模式使用类来表示文法规则,可使用继承来改变或扩展该文法。也比较容易实现文法,因为定义抽象语法树中各个节点的类的实现大体类似,这些类都易于直接编写。

    缺点:解释器模式为文法中的每一条规则至少定义了一个类,因此包含许多规则的文法可能难以管理和维护。建议当文法特别复杂时,使用其他的技术如语法分析程序或编译生成器来处理。

    结构图:

     

    访问者模式(Visitor)

    内容:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

    优点:增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者,访问者模式将有关的行为集中到一个访问者对象中。

    缺点:使增加新的数据结构变得困难了

    应用:

    ① 适用于数据结构相对稳定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。目的:要把处理从数据结构中分离出来。

     故而有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就比较合适,因为访问者模式使得算法操作的增加变的更加容易。

    结构图:

     

    中介者模式(Mediator)

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

    优点:

    ① Mediator的出现减少了各个Colleague的耦合,使得可以独立地改变和复用各个Colleague类和Mediator

    ② 由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注对象就从对象各自本身的行为转移到了他们之间的交互上来,也就是站在了一个更宏观的角度上去看待系统。

    缺点:

    由于ConcreteMediator控制了集中化,于是就把交互复杂性变为了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂。

    结构图:

     

    迭代器模式(Iterator)

    内容:提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

    应用:当你需要访问一个聚集对象,而且不管这些对象是什么,都需要遍历的时候,考虑迭代器模式;或者需要对聚集有多种方式遍历时,可以考虑使用迭代器,为遍历不同的聚集结构提供如开始,下一个,是否结束,当前哪一项等统一的接口。

    优点:迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

    结构图:

     

    备忘录模式(Memento)

    内容:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

    优点:

    ① 要保存的细节封装在Memento中,哪天要更改保存的细节也不用影响客户端了

    ② 使用备忘录可以把复杂的对象内部信息对其他对象屏蔽起来

    ③ 当角色状态改变时,有可能这个状态无效,有时候就可以使用暂时存储起来的备忘录将状态复原。

    应用:

    ① 适用于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性知识众多属性中的一小部分,Originator可以根据保存的Memento信息还原到前一状态。

    ② 如果在某个系统中使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。

    结构图:

     

    模板方法模式(TemplateMethod)

    内容:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。

    优点:

    通过把不变行为搬移到超类,去除子类中的重复代码,来体现它的优势;模板方法模式还提供了一个很好的代码复用平台;当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。

    结构图:

    展开全文
  • 行为型模式概述(行为型模式的分类) 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。 行为型模式分为类...

    行为型模式概述(行为型模式的分类)

    行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。

    行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。

    行为型模式是 GoF 设计模式中最为庞大的一类,它包含以下 11 种模式。

    1. 模板方法(Template Method)模式:定义一个操作中的算法骨架,将算法的一些步骤延迟到子类中,使得子类在可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
    2. 策略(Strategy)模式:定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。
    3. 命令(Command)模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。
    4. 职责链(Chain of Responsibility)模式:把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。
    5. 状态(State)模式:允许一个对象在其内部状态发生改变时改变其行为能力。
    6. 观察者(Observer)模式:多个对象间存在一对多关系,当一个对象发生改变时,把这种改变通知给其他多个对象,从而影响其他对象的行为。
    7. 中介者(Mediator)模式:定义一个中介对象来简化原有对象之间的交互关系,降低系统中对象间的耦合度,使原有对象之间不必相互了解。
    8. 迭代器(Iterator)模式:提供一种方法来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
    9. 访问者(Visitor)模式:在不改变集合元素的前提下,为一个集合中的每个元素提供多种访问方式,即每个元素有多个访问者对象访问。
    10. 备忘录(Memento)模式:在不破坏封装性的前提下,获取并保存一个对象的内部状态,以便以后恢复它。
    11. 解释器(Interpreter)模式:提供如何定义语言的文法,以及对语言句子的解释方法,即解释器。

    以上 11 种行为型模式,除了模板方法模式和解释器模式是类行为型模式,其他的全部属于对象行为型模式,下面我们将详细介绍它们的特点、结构与应用。

    展开全文
  • 十一大行为型模式之八:状态模式。

    景色

    十一大行为型模式之八:状态模式。

    简介

    姓名 :状态模式
    英文名 :State Pattern
    价值观 :有啥事让状态我来维护
    个人介绍
    Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.
    当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。
    (来自《设计模式之禅》)

    你要的故事

    现在有好多个人贷款软件,比如:支付宝、360借条(打广告。。。)等等。贷款会有一个用户状态流程,游客->注册用户->授信用户->借款用户(这里简化了状态,只用 4 个)。每个状态拥有的权限不一样,如下图所示。

    状态

    从上图可以看到,一个用户有 3 种行为,分别是注册、授信、借款。当注册成功后,用户的状态就从『游客』改变为『注册用户』;当授信成功后,用户的状态就从『注册用户』改变为『授信用户』;当借款成功后,用户的状态就从『授信用户』改变为『借款用户』。现在我们就来实现用户注册、授信、借款的过程,因为每个状态的权限不一样,所以这里需要根据用户的状态来限制用户行为。

    很快,我们就完成下面的代码。

    class User {
        private String state;
    
        public String getState() {
            return state;
        }
    
        public void setState(String state) {
            this.state = state;
        }
    
        public void register() {
            if ("none".equals(state)) {
                System.out.println("游客。注册中。。。");
            }else if ("register".equals(state)) {
                System.out.println("注册用户。不需要再注册。");
            } else if ("apply".equals(state)) {
                System.out.println("授信用户。不需要再注册。");
            } else if ("draw".equals(state)) {
                System.out.println("借款用户。不需要再注册。");
            }
        }
    
        public void apply() {
            if ("none".equals(state)) {
                System.out.println("游客。不能申请授信。");
            }else if ("register".equals(state)) {
                System.out.println("注册用户。授信申请中。。。");
            } else if ("apply".equals(state)) {
                System.out.println("授信用户。不需要再授信。");
            } else if ("draw".equals(state)) {
                System.out.println("借款用户。不需要再授信。");
            }
        }
    
        public void draw(double money) {
            if ("none".equals(state)) {
                System.out.println("游客。申请借款【" + money + "】元。不能申请借款。");
            } else if ("register".equals(state)) {
                System.out.println("注册用户。申请借款【" + money + "】元。还没授信,不能借款。");
            } else if ("apply".equals(state)) {
                System.out.println("授信用户。申请借款【" + money + "】元。申请借款中。。。");
            } else if ("draw".equals(state)) {
                System.out.println("授信用户。申请借款【" + money + "】元。申请借款中。。。");
            }
        }
    }
    
    public class NoStateTest {
    
        public static void main(String[] args) {
            User user = new User();
            user.setState("register");
            user.draw(1000);
        }
    
    }
    
    打印结果:
    注册用户。申请借款【1000.0】元。还没授信,不能借款。
    

    上面代码实现了用户 register (注册),apply (授信),draw (借款) 这 3 种行为,每个行为都会根据状态 state 来做权限控制。看起来有点繁琐,扩展性不高,假设新增了一个状态,那么注册、授信、借款这 3 种行为的代码都要修改。下面通过状态模式来解决这个问题。

    我们把状态给抽出来,作为一个接口,因为在每种状态中都可能有注册、授信、借款行为,所以把这 3 个行为作为状态接口的方法,让每个状态子类都实现相应的行为控制。如下代码所示。

    interface State {
    
        void register();
    
        void apply();
    
        void draw(double money);
    }
    
    /**
     * 游客
     */
    class NoneState implements State {
    
        @Override
        public void register() {
            System.out.println("游客。注册中。。。");
        }
    
        @Override
        public void apply() {
            System.out.println("游客。不能申请授信。");
        }
    
        @Override
        public void draw(double money) {
            System.out.println("游客。申请借款【" + money + "】元。不能申请借款。");
        }
    }
    
    /**
     * 注册状态
     */
    class RegisterState implements State {
    
        @Override
        public void register() {
            System.out.println("注册用户。不需要再注册。");
        }
    
        @Override
        public void apply() {
            System.out.println("注册用户。授信申请中。。。");
        }
    
        @Override
        public void draw(double money) {
            System.out.println("注册用户。申请借款【" + money + "】元。还没授信,不能借款。");
        }
    }
    
    /**
     * 授信状态
     */
    class ApplyState implements State {
    
        @Override
        public void register() {
            System.out.println("授信用户。不需要再注册。");
        }
    
        @Override
        public void apply() {
            System.out.println("授信用户。不需要再授信。");
        }
    
        @Override
        public void draw(double money) {
            System.out.println("授信用户。申请借款【" + money + "】元。申请借款中。。。");
        }
    }
    
    /**
     * 借款状态
     */
    class DrawState implements State {
    
        @Override
        public void register() {
            System.out.println("借款用户。不需要再注册。");
        }
    
        @Override
        public void apply() {
            System.out.println("借款用户。不需要再授信。");
        }
    
        @Override
        public void draw(double money) {
            System.out.println("申请借款【" + money + "】元。申请借款中。。。");
        }
    }
    
    class User1 {
        private State state;
    
        public State getState() {
            return state;
        }
    
        public void setState(State state) {
            this.state = state;
        }
    
        public void register() {
            this.state.register();
        }
    
        public void apply() {
            this.state.apply();
        }
    
        public void draw(double money) {
            this.state.draw(money);
        }
    }
    
    public class StateTest {
        public static void main(String[] args) {
            User1 user1 = new User1();
            user1.setState(new RegisterState());
            user1.apply();
            user1.draw(1000);
            user1.setState(new ApplyState());
            user1.draw(2000);
        }
    
    }
    
    
    打印结果:
    注册用户。授信申请中。。。
    注册用户。申请借款【1000.0】元。还没授信,不能借款。
    授信用户。申请借款【2000.0】元。申请借款中。。。
    

    看上面代码,我们抽象了 State 接口,4 种状态分别用 NoneState (游客)、RegisterState (注册)、ApplyState (授信)、DrawState (借款) 表示。而每个状态都有 3 种行为,它们各自对这些行为进行权限控制。这样子实现可以让权限逻辑分离开,分散到每个状态里面去,如果以后要业务扩展,要新增状态,那就很方便了,只需要再实现一个状态类就可以,不会影响到其他代码。这也是为什么《阿里巴巴 Java 开发手册》里面讲的,当超过 3 层的 if-else 的逻辑判断代码,推荐用状态模式来重构代码。

    总结

    状态模式 很好的减低了代码的复杂性,从而提高了系统的可维护性。在业务开发中可以尝试使用,比如在迭代开发中,业务逻辑越来越复杂,从而不得不使用很多 if-else 语句来实现时,就可以考虑一下是不是可以用 状态模式 来重构,特别是一些有状态流程转换方面的业务。看到这篇文章,想想工作中是不是有些复杂的代码可以重构,赶紧行动起来。

    推荐阅读:

    行为型模式:观察者模式
    行为型模式:迭代器模式
    行为型模式:策略模式

    设计模式系列文章持续更新中,欢迎关注公众号 LieBrother,一起交流学习。

    展开全文
  • 十一大行为型模式之五:策略模式。
  • 十一大行为型模式之三:命令模式。
  • 主要为大家详细介绍了C#设计模式之行为型模式的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 行为型模式分为类行为型模式和对象行为型模式,其中类行为型模式使用继承关系在几个类之间分配行为,主要通过多态等方式来分配父类与子类的职责;对象行为型模式则使用对象的关联关系来分配行为 模式名称 定义 ...
  • 设计模式:行为型模式

    2020-06-28 22:58:10
    设计模式之行为型模式 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象...
  • 一、设计模式的分类 根据其目的(模式是用来做什么的)可...• 行为型模式主要用于描述对类或对象怎样交互和怎样分配职责。 根据范围,即模式主要是用于处理类之间关系还是处理对象之间的关系,可分为类模式和...
  • 6.0行为型模式

    2020-08-19 18:07:33
    行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象行为模式,前者采用...
  • 行为型模式概述

    2019-12-12 10:52:19
    行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象行为模式,前者采用...
  • 文章目录1、创建型模式2、结构型模式3、行为型模式 1、创建型模式  前面讲过,社会化的分工越来越细,自然在软件设计方面也是如此,因此对象的创建和对象的使用分开也就成为了必然趋势。因为对象的创建会消耗掉...
  • 行为型模式简介

    2020-01-08 16:56:49
    行为型模式简介 行为型类模式使用继承描述算法和控制流,而行为型对象模式则描述一组对象怎样协作完成单个对象无法完成的任务。 一、职责链,CHAINOFRESPONSIBILITY,对象行为型模式 使多个对象都有机会处理请求...
  • 十一大行为型模式之十一:访问者模式。
  • 十一大行为型模式之七:观察者模式。
  • 十一大行为型模式之四:责任链模式。
  • 十一大行为型模式之九:备忘录模式。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,982
精华内容 7,992
关键字:

行为型模式