Java设计模式学习笔记之操作型模式

    一、操作型模式介绍:

        在编写一个Java方法时,你完成的是整个工作中级别高于单行代码的一个基本单元。这些牵方法涉到整体设计、架构以及测试以及测试计划。编写方法时面向对象编程的中心环节。但反过来说,尽管方法时软件设计的核心,我们还是难以解释方法到底是什么,方法又是如歌工作的,追本溯源,还是因为许多开发人员常常混淆了方法与操作的含义。进一步讲,算法和多态的概念比方法更加抽象,但最终它们还是通过方法来实现。

        对术语“算法”“多态”“方法”与“操作”具有清晰的认识,有助于你理解多种设计模式。尤其是状态模式、策略模式和解释器模式,都是通过实现多个类中的方法来完成操作的。但是,只有当我们对方法和操作的理解达成共识时,这样的表达才有用。

    1.操作和方法:

        操作是一个服务的规格,它可以被类的实例调用,意味着操作是方法的一抽象。

        方法时操作的实现。

    2.签名:

        方法的签名包括方法名、传入参数的数量以及类型。方法的签名不包括返回类型,尽管当一个方法重载了另一个的声明时,如

    它们的返回类型不同时,会发生编译错误。

        方法签名代表了客户调研的方法。操作是可以被请求的服务规格。当涉及不同类中的方法拥有相同的接口,使用术语“操作”。当涉及如何将Java方法调研匹配到接收对象的方法上时,使用术语“签名”。签名依赖于方法的名字和参数,但是不依赖与方法的返回类型。

    3.异常:

        正常情况下,方法会正常返回。但是,方法也可能抛出异常,或者在其内部其他方法时抛出异常。当程序正常返回时,会返

    回上次调用结束的入口点,出现异常时,则应用其他规则。        

    4.算法和多态:

        算法是已经定义好的计算程序,将数据或者数据集作为输入,将产生的数据或者数据集作为输出。算法是一个过程--一个有输入和输出的指令序列。单个的方法可能是一个算法:接收输入--参数列表--产生兵器输出其返回值。面向对象的程序中,很多算法需要多个方法来执行。

        算法完成了一些事,它可能是方法的一部分,也可能调用了很多方法。在面向对象的设计中,需要多个方法参与的算法通常依赖于多态,因为多态机制允许一个操作具有多个不同的实现。多态是一个既依赖于调用的操作,又依赖于调用接收者类型的一种方法调用的原则。

    5.超越常规的操作:

        模板方法模式:在方法中实现算法,推迟对算法步骤的定义使得子类能够重新实现

        状态模式:将操作分散,使得每个类都能够表示不同的状态。

        策略模式:封装操作,使得实现是可以互相替换的。

        命令模式:用对象来封装方法调用。

        解析器模式:将操作分散,使得每个实现能够运用到不同类型的集合中。

    二、模板方法(Template Method)模式:

        普通方法的方法体定义了一系列的指令。方法常常会调用当前对象或其他对象的其他方法。此时,可以将该普通方法看做

“模板”,它给出了计算机执行的指令序列。然而,就模板方法模式而言,它该引入一种更为特殊的模板。

        在编写某个方法时,可能需要先定义出算法的轮廓,因为该算法的实现可能五花八门。在这种情况下,就可以定义一个方法,将它的一些步骤定义为抽象方法,或者是存根方法;又或者将它们定义到一个独立的接口中。这样就产生了一个更为严格的“模板”,它特别指出了算法中的哪些步骤是由其他类提供。

        模板方法模式的意图是在一个方法里实现一个算法,并推迟定义算法中的某些步骤,从而让其他类重新定义它们。

        1.完成一个算法:

            模板方法模式与适配器模式类似,它们都允许开发者简化代码,并允许其他开发者完成代码的设计。在适配器模式中,设计者可能特定对象指定设计需要的接口,而由其他开发者提供该接口的实现。在实现时,应使用实现了不同接口的现有类所提供的服务。在模板方法模式中,设计者可能会提供一个通用的算法,而其他开发者仅提供该算法关键步骤的实现。

        2.末班方法钩子:

            钩子(hook)是一个方法回调,它可以让开发者将自己的代码插入到程序的指定位置。当希望使用其他开发者的代码时,或者希望在别的程序中插入自己的代码时,就可以使用钩子。开发者可以在你需要的时候增加一个方法调用。通常,开发者会为钩子提供一个存根实现。一旦其他客户端就不再需要钩子,就没有必要再重写它。

        3.重构为模板方法模式:

            在使用模板方法模式时,发现在类继承关系中,超类提供的是算法的描述,而子类提供的是算法具体步骤。当发现不同的方法具备相似的算法时,就可以将它们重构为末班方法模式(重构是在不改变程序功能的前提下,用更好的设计重新实现。

        4.模板模式的角色及实例示例:

            模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法及具体构造函数的形式,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余逻辑有不同的实现。这就是模板方法的用意。

            抽象类(AbstractClass):实现了模板方法,定义了算法的骨架

public abstract class AbstractImageLoader {

    //抽象类定义整个流程骨架
    public final void downloadImage(String imageUrl,int width,int height){
        //先获取最终的数据源URL
        String finalImageUrl=getUrl(imageUrl,width,height);
        //然后开始执行下载
    }
    //以下是不同子类根据自身特性完成的具体步骤
    protected abstract String getUrl(String imageUrl,int width,int height);
}

            具体类实现:

public class WebpImageLoader extends  AbstractImageLoader {
    @Override
    protected String getUrl(String imageUrl, int width, int height) {
        return String.format("%s?imageView2/1/w/%d/h/%d/format/webp", imageUrl, width, height);
    }
}

     三、状态(State)模式:

            对象状态是指对象属性的当前值得组合。在调用对象的set方法,或给对象的成员变量赋值时,都是在改变对象的状态。通常在执行对象的方法时,其自身状态也会改变。

            有一种办法可以获知与状态相关的逻辑分布情况:引入一组新的类,每个类代表不同的状态,然后将与状态相关的行为分别写到每个类中。

            状态模式的意图是将表示对象状态的逻辑分散到代表状态的不同类中。

            1.状态模式的角色及实例示例:

                定义State

//定义和Context中的状态相对应的行为
 public interface State {
     //获取天气情况
    String getState();
 }

               定义Context:

 //定义当前的状态
 public class Context {
     private State state;
     public State getState() {
         return state;
    }
    public void setState(State state) {
         this.state = state;
    }
     public String stateMessage(){
         return state.getState();
    }
 }

        定义ConcreateStatesubclasses

class Sunshine implements State{
     @Override
     public String getState() {         
         return "晴天";
    }
     
 }
 class Rain implements State{
 
     @Override
     public String getState() {
        
        return "下雨";
     }
     
 }

    四、策略(Strategy)模式:

            策略模式是一个计划或者方式,根据给定的输入条件达成一个目标。策略和算法很相似,算法时一段程序,它可以对一组输入进行处理,获得输出。通常情况下,策略提供的范围比算法要广泛。这就意味着侧路通常会提供一组做一族可互换的方法。

             当一个计算机程序存在很多策略时,代码就会变得复杂。要从一组策略中选择合适的策略,选择逻辑自身可能会很复杂。

     当多种策略的选择与执行导致复杂度增加时,就可以使用策略模式来简化它。

             策略操作定义了策略的输入与输出,实现则由各个独立的类完成。这些类的实现虽然不同。但是由于接口是一直的,因此可以使用相同的接口给用户提供不同的策略进行互换。策略模式可以让一组策略共存,代码互不干扰。它还将选择策略的逻辑从策略本省中分离了出来。

              策略模式的意图是将可互换的方法封装在各自独立的类中,并且让每个方法都实现一个公共的操作。

    1.策略建模:

    策略模式通过将问题的不同的解决方法封装在不同的类中,以帮助组织和简化代码。

    -创建一个接口来定义策略操作;

    -分别用不同的类实现该策略接口;

    -重构代码,选择使用正确的策略类。

    2.比较策略模式与状态模式:

        一方面,状态模式和策略模式的模型区别微乎其微。显然,多台使得状态模式和策略模式的结构看起来几乎完全一致。

        另一方面,在现实生活中。策略和状态是两种完全不同的思想。在对状态和策略进行建模时,这种现实的差异就会带来不同的问题。如在对状态进行建模时,状态的迁移至关重要:而对策略的建模却无须考虑这一问题。另一个区别是,策略模式允许客户选择或者提供某个策略,而状态模式却很少这样设计。

    3、小结:

        不同策略模型的逻辑可能会放到同一个类中,并常常写在一个方法里。这样的方法可能过于复杂。并且混合了策略的选择逻辑和执行逻辑。为了简化这样的代码,需要创建一组类。每个类代表一种策略。定义一个接口方法。并让这些类都实现它。这就使得每个类都封装了一种策略,代码也会变得简单。同时,还需要为策略提供选择逻辑。该逻辑在重构后仍然可能比较复杂,但是可以简化这些代码,使其等价于问题域中描述策略的伪代码。

        典型情况下,客户会使用一个上下问变量来维护策略的选择。通过将策略操作的调用转发给上下文,并使用多台执行正确的策略,也可以使得策略的执行变得更简单。策略模式将可相互替换的策略封装到不同的类,并让这些类实现一个公共接口。这样就可以帮组我们创建简洁的代码,为解决问题的各种方式建立统一的模型。

    五、命令(Command)模式:

        直接调用是执行方法的一般方式。然而,有时我们无法控制方法执行的时机与上下文。这种情况下,可以将方法封装在对象的内部。通过在对象内部存储调用方法所需要的信息。就可以让客户端或者服务决定何时调用该方法。

        命令模式的意图是将请求封装在对象内部

        命令模式可以将请求封装在一个对象中,允许你可以像管理对象一样去管理方法,传递并且在合适的时机去调用它们。菜单是应用命令模式的一个经典案例。菜单项知道何时执行一个请求。但却不知道应该去执行什么请求。命令模式可以让你使用与菜单标签相关的方法调用作为参数,传递一个菜单。

        命令模式的另一个用处是,允许在服务执行客户类代码。服务经常在调用客户代码的前后执行。最后,除了可以控制方法的执行时间和上下文外。命令模式还可以提供一个钩子机制,允许客户代码作为算法执行的一部分。

        命令模式将请求封装在对象中,因此你可以像操作对象那样来操作请求。或许是因为这种想法如此普遍,通常命令模式会和其他模式一起使用。如命令模式可以作为模板方法模式的一种代替模式,它也经常和调停者模式与备忘录模式配合使用。

    六、解释器(Interpreter)模式:

        和命令模式一样,解释器模式也产生一个可执行的对象。不同的是,解释器模式创建了一个类层次,该层次中的每个类都实现或者解释了一个公共操作,并且该操作的名称与类名相同。从这点来看,解释器模式与状态模式和策略模式都和相似。在这些模式各自的类集合中,都有一个公共的方法,但是每个类对该方法的实现都不一样。

    解释器模式和合成模式很相似,合成模式通常会定义一个公共接口,该接口用于单个对象或者复合对象。合成模式并不要求必须以不同的方式组织结构。

     解释器模式的意图是让你根据事先定义好的一系列组合规则,组合可执行对象。

    解释器模式可以让你根据创建的类层次结构来组合可执行对象。层次结构中的每个类都实现了一个公共的操作。

    每个类的名称通常暗指该类所要实现或解释的通用操作,每个类要么定义合成命令的方式。要么表示执行某些操作的终端命令。设计解释器常常会引入变量,以及布尔或者算术表达式。解释器也经常和解析器一起使用。用来创建一个轻量级的语言,简化新的解释器对象的创建。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java设计模式是一套被广泛应用于Java编程的经典设计思想和解决方案。它们帮助开发人员解决常见的软件设计问题,并提供了可重用的代码模板。下面是一些常见的Java设计模式: 1. 创建模式(Creational Patterns): - 工厂模式(Factory Pattern):通过工厂方法创建对象,隐藏对象的创建逻辑。 - 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无需指定具体类。 - 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供全局访问点。 - 建造者模式(Builder Pattern):将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。 - 原模式(Prototype Pattern):通过复制现有对象来创建新对象,避免了使用new操作符。 2. 结构模式(Structural Patterns): - 适配器模式(Adapter Pattern):将一个类的接口转换成客户端所期望的另一个接口。 - 桥接模式(Bridge Pattern):将抽象部分与实现部分分离,使它们可以独立变化。 - 组合模式(Composite Pattern):将对象组合成树形结构以表示“部分-整体”的层次结构。 - 装饰器模式(Decorator Pattern):动态地给一个对象添加额外的职责。 - 外观模式(Facade Pattern):为子系统中的一组接口提供一个统一的接口。 - 享元模式(Flyweight Pattern):通过共享对象来减少内存使用,提高性能。 3. 行为模式(Behavioral Patterns): - 模板方法模式(Template Method Pattern):定义一个算法的骨架,将一些步骤延迟到子类中实现。 - 策略模式(Strategy Pattern):定义一系列算法,将它们封装起来,并使它们可以互相替换。 - 观察者模式(Observer Pattern):定义对象间的一种一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知。 - 迭代器模式(Iterator Pattern):提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。 - 命令模式(Command Pattern):将请求封装成对象,使得可以用不同的请求对客户进行参数化。 - 责任链模式(Chain of Responsibility Pattern):将请求的发送者和接收者解耦,使多个对象都有机会处理这个请求。 - 状态模式(State Pattern):允许对象在内部状态改变时改变它的行为。 - 访问者模式(Visitor Pattern):在不改变对象结构的前提下,定义作用于对象结构中元素的新操作

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值