2010-09-29 95 views
1

不确定如何描述这个肯定,但我想我已经搞清楚了我想在标题中做什么。详细说明一下,我正在寻找一种设计模式,它可以让我实现一种服务,在一种情况下可以同步返回调用的结果,但在另一种情况下,会返回有关如何异步完成调用的详细信息(例如作业ID)。设计一个服务接口,以允许同步和异步实现

也许只是通过定义这样的问题,很明显,我试图做的事情打破了设计接口契约的想法。完全可能朝着错误的方向前进。

我在想的是可能是这样的:

public class Data { 
    private int id; 
    /* getter/setter */ 
} 

public class QueuedData extends Data { 
    private int jobId; 
    /* getter/setter */ 
} 

public interface MyService { 
    public Data fetchData(int id); 
} 

public class SyncedMyService implements MyService { 
    private SyncDao syncDao; 
    public Data fetchData(int id) { 
    return syncDao.getData(id); 
    } 
} 

public class QueuedMyService implements MyService { 
    private JobQueue queue; 
    public QueuedData fetchData(int id) { 
    int jobId = queue.startGetData(id); 
    QueuedData queuedData = createQueuedDate(jobId); 
    return queuedData; 
    } 
} 
 

这是一个明智的方式去了解这项任务?感谢您的任何建议。 (这可能是我应该阅读的设计模式书)

回答

1

这与java.util.concurrent软件包中使用的Future模式非常相似。 A Future表示在单独的线程中完成计算后将来可用的结果。如果在需要结果之前计算已经完成,则返回计算值。否则调用获得结果块直到计算结束。

所以我认为这种模式是同步和异步服务的正确方法。

这是如何实现使用Future解决方案:

public class Data { 
    private int id; 
    private final String name; 

    Data(String name) { this.name = name; } 
    public String getName() { return name; } 
} 

public class FutureData extends Data { 
    private int id; 
    private final Future<String> nameFuture; 

    FutureData(Future<String> nameFuture) { this.nameFuture = nameFuture; } 
    @Override public String getName() { return nameFuture.get(); } 
} 

public interface MyService { 
    public Data fetchData(int id); 
} 

public class SyncMyService implements MyService { 
    private SyncDao syncDao; 
    public Data fetchData(int id) { 
    return syncDao.getData(id); 
    } 
} 

public class AsyncMyService implements MyService { 
    private static final ExecutorService executor = 
    Executors.newFixedThreadPool(10); 

    public FutureData fetchData(final int id) { 
    Future<String> future = executor.submit(new Callable<String>() { 
     public String call() { 
     String name; 
     //some long computation that computes the name using the id given 
     return name; 
     } 
    }); 
    FutureData futureData = new FutureData(future); 
    return futureData; 
    } 
} 

石英刚刚与JobQueue更换ExecutorService和使用Quartz中的等价物Future

+0

整洁,没有听说过那个包,我得看看它。我不确定它在我的场景中会有用,因为我可能会使用Quartz进行“背景”任务。 – 2010-09-29 18:37:22

1

这是继承的良好用法。您的SynchedMyService和QueuedMyService遵循由MyService指定的合同/规则。

而且由具有fetchData()方法返回一个类型的数据,你让自己建立在数据对象上,并返回更复杂的对象(如QueuedData)

如果你不想能力有每个类实例化的逻辑。看看Factory design pattern来帮助你,因为你继续增长你的应用程序