且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在函数调用中强制执行序列

更新时间:2023-12-01 14:47:34

您可能对步骤生成器模式。这不一定是您提供的所有情况的一个很好的匹配,但是想法是每个操作返回一些实现接口的操作,让您执行下一个操作。由于您只能以正确的顺序执行操作来获取对象,因此您将***以正确的顺序执行。



虽然感觉有点强制在迭代(next / hasNext)的情况下,您可以想象它为您的袜子上的





  • 然后穿上你的鞋子



不知怎的,你得到一个 CanWearSocks 接口的实例,它只有以下方法。

  CanWearShoes putOnSocks()

当您调用 putOnSocks() / code>,您将获得 CanWearShoes 实例,该实例只有以下方法。

  SockAndShoeWearer putOnShoes()

当您调用 putOnShoes ()你现在有东西穿袜子和鞋子,你***按正确的顺序做。



什么是特别好的是您可以在这两种情况下实际使用相同的对象,但是由于方法签名只返回接口类型,代码将只能使用接口方法(除非代码是鬼祟的,并将对象转换为不同的类型)。 / p>

示例



这是一个非常有创意的实例,它实现了迭代模式,即确保你在NextGetter之前使用NextChecker。

  public class StepBuilderIteration {

interface NextChecker {
NextGetter hasNext();
}

接口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){
返回新的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


Let's say I want to design a class whose clients would need to call functions in a particular sequence, e.g.,

hasNext();
next();

or, as a very generic example, a class CookFood with methods:

class CookFood {
  getListOfItems();
  mixAllItems();
  heat();
}

In the second example, I want to enforce that mixing should be done only after getting items, and that heating should be done only after mixing. Are there any known patterns or good practices that enforce sequence of function calls?

You might be interested in the Step Builder Pattern. It's not necessarily a good match for all the cases that you've presented, but the idea is that each operation returns something implementing an interface that lets you perform the next operation. Since you can only get the objects by performing the operations in the correct order, you'll be forced to perform them in the correct order.

While it would feel a bit forced in the iteration (next/hasNext) situation, you can imagine it for the

  • put on your socks,
  • then put on your shoes

pattern. Somehow you get an instance of the CanWearSocks interface, which has only the following method.

CanWearShoes putOnSocks()

When you call putOnSocks(), you get your CanWearShoes instance, which has only the following method.

SockAndShoeWearer putOnShoes()

When you call putOnShoes() you now have something wearing socks and shoes, and you were forced to do it in the correct order.

What's particularly nice is that you can actually use the same object in both cases, but because the method signatures only return the interface type, code will only be able to use the interface methods (unless the code is sneaky, and casts the object to a different type).

Example

Here's a rather contrived example that implements the iteration pattern, i.e., that makes sure that you use a NextChecker before a NextGetter.

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();
            }
        }
    }
}

The output is:

1
2
3
4