在不同线程上执行接口的两个不同实现

Have two different Implementations for an interface execute on different thread

我有一个接口说 VegetableCreation 有一个方法:

public void writeVeggieDataIntoFile();

和两个不同的 class 称为 AppleMango 实现 VegetableCreation.

还有一个工厂 class VegetableFactory 有一个 create() 方法:

public class VegetableFactory {
    public VegetableCreation create(String arg0) {

        if (arg0.equals("Apple"))
           return new Apple();
        else if (arg0.equals("Mango")
           return new Mango();
        else {
           // create and return both apple and mango by spawning two different threads
           // so that the writeVeggieDataIntoFile();  gets invoked concurrently
           // for both apple and mango and two different file is created
        }
    }
}

我基本上想在这里实现的是,当我从客户端 class 的 [=] 调用 VegetableFactory class 的 create() 方法时20=] 方法并将 "Apple""Mango" 以外的任何字符串值作为 运行 时间参数传递。我希望两个不同的线程在每个 AppleMango 对象上工作,并同时在每个 writeVeggieDataIntoFile() 方法上工作。

任何有关设计策略/或使用哪些并发 API 等的建议都将不胜感激。

P.S.: 我应该称它为水果**而不是蔬菜*

首先,我希望您的工厂具有静态创建功能。然后在create do item instanceof Fruit 然后创建水果线程。 else if item instanceof Vegetable then do vegetable thread.

研究 Composite 模式,然后构建一个 CompositeVegetable,当它被告知 "do it's thing" 时会启动两个线程,一个做一件事,另一个做另一件事。

public class BothVegetable implements Vegetable {
    public void writeVeggieDataInfoFile() {
        Thread thread1 = new Thread(new AppleRunnable());
        Thread thread2 = new Thread(new MangoRunnable());
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
    }
}

// and in your factory

    return new CompositeVegetable();

PS。你的蔬菜在我看来像水果!

我希望从一家名为 VegetableFactory/FruitFactory 的工厂获得 Vegetable/Fruit,而不是 VegetableCreation/FruitCreation.

我会避免线程创建和文件写入作为工厂方法中的副作用。

我也会 rename/change writeFruitDataIntoFile()write(Writer out) 因为你写的东西是由封闭的接口或 class 告诉的,而你写的地方是由它告诉的方法参数。

如果真的需要并发处理,在write(...)中创建一个线程,让工厂方法简单的return一个Fruit.

优点是:

  • 创建对象时没有必须记录的副作用。
  • 线程仅按需创建(在调用 write() 的情况下),而不是在每个 Fruit 对象创建时创建。
  • 您不需要额外的 class。
  • 每个了解工厂设计模式的人第一眼就能理解它的简洁实现。

参见:

为了良好的 OO 实践,我会使用一个接口:

interface Fruit {

  void write(Writer out);

  ...
}  // Fruit

它的抽象实现:

public abstract class AbstractFruit implements Fruit {

  Data data;

  public void write(Writer out) {
    ...
  }

  ...
}  // AbstractFruit

public classe Apple extends AbstractFruit implements Fruit {
  ...
}

public classe Mango extends AbstractFruit implements Fruit {
  ...
}

为了 type safety I'd use specific get...() methods (as it is often done in the Java API):

public class FruitFactory {

  public static Fruit getApple() {
     Fruit a = new Apple()
     ...
     return a;
  }

  public static Fruit getMango() {
     Fruit m = new Mango()
     ...
     return m;
  }
}  // FruitFactory

enum:

interface Fruit {

  enum Type {
    APPLE,
    MANGO 
  }

  void write(Writer out);

  ...
}  // Fruit

public class FruitFactory {

  public static Fruit get(Fruit.Type fruitType) {

     switch (fruitType) {
        case Fruit.Type.APPLE:
          Fruit a = new Apple()
          ...
          return a;
          break;
        case Fruit.Type.MANGO:
          Fruit m = new Mango()
          ...
          return m;
          break;
        default:
          throw new FruitTypeNotSupported/* Runtime, i.e. unchecked */Exception();
          break; 
     }
  }  // get(...)
}  // FruitFactory

请参阅 RuntimeException 的 API 文档:

Unchecked exceptions do not need to be declared in a method [...] throws clause