假设我要设计一个类,其客户需要按特定顺序调用函数,例如,

hasNext();
next();

或者,作为一个非常通用的示例,是带有方法的类CookFood:
class CookFood {
  getListOfItems();
  mixAllItems();
  heat();
}

在第二个示例中,我要强制执行混合操作,只有在拿到物品后才进行,而加热则应在混合后才进行。是否存在任何已知的强制执行函数调用顺序的模式或良好实践?

最佳答案

您可能对Step Builder Pattern感兴趣。它不一定适合您所提出的所有情况,但其思想是每个操作都返回一些实现接口(interface)的内容,该接口(interface)可让您执行下一个操作。由于只能通过以正确的顺序执行操作来获取对象,因此您将被迫以正确的顺序执行对象。

尽管在迭代(next/hasNext)情况下会感到有些强制,但您可以想象一下

  • 穿上 socks
  • 然后穿上鞋子

  • 模式。您会以某种方式获得CanWearSocks接口(interface)的实例,该实例只有以下方法。
    CanWearShoes putOnSocks()
    

    调用putOnSocks()时,您将获得CanWearShoes实例,该实例只有以下方法。
    SockAndShoeWearer putOnShoes()
    

    现在,当您调用putOnShoes()时,您会穿一些穿 socks 和鞋子的东西,而您被迫按正确的顺序进行操作。

    特别好的是,在两种情况下您实际上都可以使用相同的对象,但是由于方法签名仅返回接口(interface)类型,因此代码将只能使用接口(interface)方法(除非代码是偷偷摸摸的,并将对象强制转换为不同类型)。



    这是一个实现迭代模式的相当人为的示例,即确保您在NextGetter之前使用NextChecker。
    public class StepBuilderIteration {
    
        interface NextChecker {
            NextGetter hasNext();
        }
    
        interface NextGetter {
            Object next();
            NextChecker more();
        }
    
        static class ArrayExample {
            final static Integer[] ints = new Integer[] { 1, 2, 3, 4 };
    
            public static NextChecker iterate() {
                return iterate( 0 );
            }
    
            private static NextChecker iterate( final int i ) {
                return new NextChecker() {
                    public NextGetter hasNext() {
                        if ( i < ints.length ) {
                            return new NextGetter() {
                                public Object next() {
                                    return ints[i];
                                }
                                public NextChecker more() {
                                    return iterate( i+1 );
                                }
                            };
                        }
                        else {
                            return null;
                        }
                    }
                };
            }
        }
    
        public static void main(String[] args) {
            NextChecker nc = ArrayExample.iterate();
            while (nc != null) {
                NextGetter ng = nc.hasNext();
                if (ng != null) {
                    System.out.println(ng.next());
                    nc = ng.more();
                }
            }
        }
    }
    

    输出为:

    1
    2
    3
    4
    

    10-06 07:24
    查看更多