溶液
构建这种流畅的 API 模式的一个好方法是,不要只从每个方法返回,而是返回一个实例,该实例实现的 a 仅支持应位于列表中的方法,并让最后一个方法调用返回您需要的实际对象。thisMethod Object PatternInterfacenext
如果这是获取该对象实例的唯一方法,则始终必须调用最后一种方法。
package com.stackoverflow;
import javax.annotation.Nonnull;
import java.util.Date;
public class Q6613429
{
    public static void main(final String[] args)
    {
        final Rights r = PermissionManager.grantUser("me").permissionTo("ALL").item("EVERYTHING").asOf(new Date());
        PermissionManager.apply(r);
    }
    public static class Rights
    {
        private String user;
        private String permission;
        private String item;
        private Date ofDate;
        private Rights() { /* intentionally blank */ }
    }
    public static class PermissionManager
    {
        public static PermissionManager.AssignPermission grantUser(@Nonnull final String user)
        {
            final Rights r = new Rights(); return new AssignPermission() {
                @Override
                public AssignItem permissionTo(@Nonnull String p) {
                    r.permission = p;
                    return new AssignItem() {
                    @Override
                    public SetDate item(String i) {
                        r.item = i;
                        return new SetDate()
                    {
                        @Override
                        public Rights asOf(Date d) {
                            r.ofDate = d;
                            return r;
                        }
                    };}
                };}
            };
        }
        public static void apply(@Nonnull final Rights r) { /* do the persistence here */ }
        public interface AssignPermission
        {
            public AssignItem permissionTo(@Nonnull final String p);
        }
        public interface AssignItem
        {
            public SetDate item(String i);
        }
        public interface SetDate
        {
            public Rights asOf(Date d);
        }
    }
}
这强制执行了构造调用链,并且对代码完成非常友好,因为它显示了下一个接口是什么,并且只有方法可用。
下面是一个更完整的示例,中间是可选内容:
UrlBuilder.java
这提供了一种万无一失的检查异常免费方法来构造对象。URL
将持久性与构造混合在一起是混合问题:
创建对象和存储对象是不同的关注点,不应混合使用。考虑到这并不意味着,反之亦然,并指出关注点的混合立即在不同的地方做不同的事情,你得到你想要的保证。.build().store()buildAndStore()
将对持久性代码的调用放在另一个方法中,该方法仅接受 完全构造的 实例。Rights