zoukankan      html  css  js  c++  java
  • Java链式方法 连贯接口(fluent interface)

    有两种情况可运用链式方法:

    第一种  除最后一个方法外,每个方法都返回一个对象

    object2 = object1.method1();

    object3 = object2.method2();

    object3.method3();

    以上三行代码等价于如下链式方法

    object1.method1().method2().method3();

    第二种 调用同一个对象的多个方法

    user.setName(String name);

    user.setPassword(String password);

    user.setRole(String role);

    以上三行代码等价于如下链式方法

    user

          .setName(String name)

          .setPassword(String password)

          .setRole(String role);

    示例:

    使用chaining:

    package com.dxz.base;
    
    public class Persion {
        private int id;
        private String name;
        private String phoneNumber;
        private String address;
    
        public Persion() {
    
        }
    
        public Persion setId(int id) { 
            this.id = id;
            return this;
        }
        public Persion setName(String name) {
            this.name = name;
            return this;
        }
        public Persion setPhoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
            return this;
        }
        public Persion setAddress(String address) {
            this.address = address;
            return this;
        }
        public Persion printId() {
            System.out.println(this.id);
            return this;
        }
        public Persion printName() {
            System.out.println(this.name);
            return this;
        }
        public Persion printPhoneNumber() {
            System.out.println(this.phoneNumber);
            return this;
        }
        public Persion printAddress() {
            System.out.println(this.address);
            return this;
        }
    }
    package com.dxz.base;
    
    public class Test {
        public static void main(String[] args) {
            /*Persion persion1 = new Persion();
            persion1.setId(3);
            persion1.setName("John");
            persion1.setPhoneNumber("1111111");
            persion1.setAddress("US");
            persion1.printId();
            persion1.printName();
            persion1.printPhoneNumber();
            persion1.printAddress();*/
            Persion persion1 = new Persion();
            persion1.setId(3).setName("John")
                    .setPhoneNumber("1111111").setAddress("US");
            persion1.printId()
                    .printName()
                    .printPhoneNumber()
                    .printAddress();
        }
    }

    结果:

    3
    John
    1111111
    US

    直到前一段开始看老马的《特定领域语言》这本书才知道这种用法是一种DSL,老马还给他起了一个名字 连贯接口(fluent interface)。

    关于DSL,它最大的用处就是:将常见模式抽取出来,使之变成更加有可读性的描述方式。是的!有好的可读性:你之所以觉得正则表达式(另一种DSL)比一堆String解析代码难读,是你没有付出学习正则表达式的时间。当你掌握了一种DSL的规则后,你会觉得它更简便,更具有可读性,你要付出的是学习成本,而带来的则是效率的提高,与眼前的清爽。

    上面的3个例子中,我们发现阅读更加简便,代码量也减少了很多。那么它是如何实现的呢?其实很简单,你可以把它看做是一种责任链模式的简写/变种。我们看一段示例代码,这段代码中,创建了一个AppoinetmentCalendarChained 的实例calendar。对calendar进行了链式操作:add().from().to().at()

    复制代码
    public class CalendarDemoChained {
    
        public static void main(String[] args) {
            new CalendarDemoChained();
        }
    
        public CalendarDemoChained() {
            Calendar fourPM = Calendar.getInstance();
            fourPM.set(Calendar.HOUR_OF_DAY, 16);
            Calendar fivePM = Calendar.getInstance();
            fivePM.set(Calendar.HOUR_OF_DAY, 17);
    
            AppointmentCalendarChained calendar =
                    new AppointmentCalendarChained();
            calendar.add("dentist").
                    from(fourPM).
                    to(fivePM).
                    at("123 main street");
    
            calendar.add("birthday party").at(fourPM);
            displayAppointments(calendar);
        } 
    
        private void displayAppointments(AppointmentCalendarChained calendar) {
            for (Appointment a : calendar.getAppointments())
                System.out.println(a.toString());
        }
    }
    复制代码

    实现链式操作的类

    复制代码
    public class Appointment {
        private String _name;
        private String _location;
        private Calendar _startTime;
        private Calendar _endTime;
    
        public Appointment(String name) {
            this._name = name;
        }
    
        public Appointment() {
        }
    
        public Appointment name(String name) {
            _name = name;
            return this;
        }
        public Appointment at(String location) {
            _location = location;
            return this;
        }
    
        public Appointment at(Calendar startTime) {
            _startTime = startTime;
            return this;
        }
    
        public Appointment from(Calendar startTime) {
            _startTime = startTime;
            return this;
        }
    
        public Appointment to(Calendar endTime) {
            _endTime = endTime;
            return this;
        }
    
        public String toString() {
            return "Appointment:"+ _name +
                    ((_location != null && _location.length() > 0) ? 
                        ", location:" + _location : "") +
                    ", Start time:" + _startTime.get(Calendar.HOUR_OF_DAY) +
                    (_endTime != null? ", End time: " + 
                    _endTime.get(Calendar.HOUR_OF_DAY) : "");
        }
    }
    复制代码

    我们来看add from to 这些方法。每个方法调用后都把实例本身返回了进去,java支持匿名调用,这样就可以直接调用自身方法了,其实挺简单的。

    当链式操作有顺序的时候(如某些操作必须有一些前置操作),就要多封装一些复杂逻辑了,老马的书里有很多丰富的思路介绍(第10,11,33,38,50章),但并不是非常详细,需要自己再拓展阅读。

    btw,要多说2句的是,连贯接口只是DSL的一种,2个常见的测试相关框架已经在大量使用了。去年用的较多的Robotframework 使用的关键字驱动也是一种典型的DSL。多学习抽象的方法对自动化框架的设计应该说有很大好处。

    参考书籍:《特定领域语言》

    参考链接:

    1.http://martinfowler.com/bliki/FluentInterface.html

    2.http://www.ibm.com/developerworks/cn/java/j-eaed13/

    3.http://jmock.org/oopsla2006.pdf

  • 相关阅读:
    ReentrantLock 非公平锁不公平在哪
    spring 初始化Bean
    spring 循环引用问题,在一次问题调试过程中发现有个小伙伴竟然把循环引用设置成false了。估计是百度的时候没小心额外的代码吧。。。
    Maya2019下载安装与激活
    Maya2014下载安装与激活
    Maya2017下载安装与激活
    Windows 好用的护眼软件
    万兴全能格式转换器_11.2.0.232 下载安装和激活
    处理视频相关的软件
    几款好用的录屏软件推荐
  • 原文地址:https://www.cnblogs.com/duanxz/p/5384958.html
Copyright © 2011-2022 走看看