适应方法调用的Builder模式 [英] Adapting the Builder pattern for method invocation

查看:104
本文介绍了适应方法调用的Builder模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是试图从有效Java第2版中了解第40项:小心设计方法签名的部分。

This is an attempt to understand a portion of ITEM 40: Design Method Signatures Carefully from Effective Java 2nd Edition.

建议改进方法签名可读性的事情是针对四个或更少的参数。建议使用多种技术来管理更长的参数列表,其中之一如下:

One of the things suggested to improve method signature readability is to aim for four or fewer parameters. It is suggested that longer parameter lists be managed by using a variety of techniques one of which is as follows :


结合方面的第三种技术前两个是将
将Builder模式(Item 2)从对象构造调整到方法
调用。如果你有一个有很多参数的方法,特别是如果
其中一些是可选的,那么定义一个代表所有参数的对象
是有好处的,并允许客户端使
多个setter调用此对象,每个都设置单个
参数或一个小的相关组。一旦设置了所需的参数
,客户端将调用对象的execute方法,该方法对
进行任何对参数的最终有效性检查,并执行实际的
计算。

A third technique that combines aspects of the first two is to adapt the Builder pattern (Item 2) from object construction to method invocation. If you have a method with many parameters, especially if some of them are optional, it can be beneficial to define an object that represents all of the parameters, and to allow the client to make multiple "setter" calls on this object, each of which sets a single parameter or a small, related group. Once the desired parameters have been set, the client invokes the object’s "execute" method, which does any final validity checks on the parameters and performs the actual computation.

我熟悉Builder模式,因为它用于对象构造,但不知道我是否已经正确地了解了如何使它适应于方法调用。

I am familiar with the Builder pattern as it is used for object construction, but am not sure whether I have correctly understood how to adapt it to method invocation.

这是我到目前为止:

(我已经尝试改进方法调用的 move 方法)

Here is what I have thus far :
( I have attempted to improve the method invocation for the move method)

public class Space {

    public static class Builder {
        // Required parameters
        private final int x;
        private final int y;
        private final int z;

        // optional params
        private long time = 0;

        public Builder(int x, int y, int z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        public Builder time(long val) {
            time = val;
            return this;
        }

        public void move() {
            if (x == 0 || y == 0 || z == 0) {
                throw new IllegalArgumentException("Cannot move to the centre of the universe");
            }

            // Do the actual work here
        }
    }

//  public void move(int x, int y, int z, long time) {
//      // Do the work here
//  }

    public static void main(String[] args) {
        new Builder(1, 1, -1).time(1234).move();
    }
}

我对Joshua Bloch的建议的解释是否正确? p>

Is my interpretation of Joshua Bloch's advice correct ?

推荐答案

我使用我想要实例化的类中定义的接口完成了Builder模式的验证。

I've done reifications of the Builder pattern using an interface defined inside the class I want to instantiate.

有关这个和相关的双向构建器的更多信息,请参阅这里: http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox.html?page=3

See here for extra info on this and the related "bidirectional builder": http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox.html?page=3

我会做如下的事情:虽然这对于3个必填字段可能是过分的,但是对于构建较大的对象而言,这对于每个必需字段都是非常有帮助的。

I would do something like the following; although this is overkill perhaps for 3 required fields, it is very helpful for constructing larger objects while accounting for every required field.

public Class Space
{    
    public interface Builder
    {
        public Space build();
        public int x();
        public int y();
        public int z();
    }

    // Build a complete Space object accounting for every field. 
    public Space(Space.Builder spaceBuilder)
    {
        this.x = spaceBuilder.x();
        this.y = spaceBuilder.y();
        this.z = spaceBuilder.z();
        this.time = builder.time();
    }

    // Might not be necessar if you update time when you update x, y, and z
     public Builder time(long val)
     {
            time = val;
            return this;
     }

     public void move()
     {
        // ...
     }

    public static void main(String[] args)
    {
        new Builder()
        {   
            @Override
            public Space build(){ return new Space(this);}

            @Override
            public int x(){ return 1;}

            @Override
            public int y{ return 1;}

            @Override int z{ return -1;}
        }.build().time(1234).move();
    }
}

这篇关于适应方法调用的Builder模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆