Java 铸造vs复制代码:两个给定选项中的最佳选项是什么?

Java 铸造vs复制代码:两个给定选项中的最佳选项是什么?,java,oop,design-patterns,Java,Oop,Design Patterns,情况(下面给出的UML):java包应该有一个类进程,在线程内的循环中运行计算,并将计算结果通知观察者。通过将类外部的值添加到线程可以读取的队列,将启动新的计算: public class Process { /* ... */ Thread th; BlockingQueue queue = new ArrayBlockingQueue(10); public void calc() { th = new Thread(new Runnable() { pub

情况(下面给出的UML):java包应该有一个类进程,在线程内的循环中运行计算,并将计算结果通知观察者。通过将类外部的值添加到线程可以读取的队列,将启动新的计算:

public class Process
{
/* ... */
Thread th;
BlockingQueue queue = new ArrayBlockingQueue(10);

public void calc()
{
    th = new Thread(new Runnable()
    {
        public void run()
        {
            while (!Thread.currentThread().isInterrupted())
            {
                try
                {
                    Integer value = (Integer) queue.take();
                    List<Float> result = calculator.calcAllResults(value);
                    /* ... Do something with result ...*/
                } catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }).start();
}

public void addValue(Integer value)
{
    queue.add(value);
}
/* ... */
}
设计2:

CalCalResults()方法现在位于AbstractCalculationStrategy类型的对象中。从这个抽象类中存在两个(将来可能更多)子类:CalculationStrategy1和CalculationStrategy2。两者都单独定义calCalResults()。例如:

public class CalcType1A extends AbstractCalculationType
{
/* ... */

private DataType1 data;

public float calcSingleResult(AbstractDataObject data)
{
    this.data = (DataType1) data;
}

/* ... */
}
public class CalculationStrategy1 extends AbstractCalculationStrategy
{
/* ... */

private DataGatherer1 dataGatherer1;
private List<AbstractCalculationType1> calculators; 

public float calcAllResult(int value)
{
    List<Float> result = new List<Float>();
    DataType1 dt1 = dataGatherer1.getData(value);
    for (int i = 0; i < calculators.size(); i++)
    {
        result.add(calculators.get(i).calcSingleResult(dt1));
    }
}

/* ... */
}
公共类CalculationStrategy1扩展了AbstractCalculationStrategy
{
/* ... */
专用数据采集器1数据采集器1;
私人名单计算器;
公共浮点CalCalResult(int值)
{
列表结果=新列表();
DataType1 dt1=dataGatherer1.getData(值);
对于(int i=0;i
(与CalculationStrategy2相同,但使用DataGatherer2对象和AbstractCalculationType2对象。)

这基本上是上述情况,即只存在一种计算类型。这里的优势是每个策略必须收集其计算器对象真正需要的特定数据类型(无强制转换)。的缺点是您有重复的代码:CalCalCalResult()方法中的逻辑对于两种(将来可能更多)计算策略是相同的(或者:将来必须以相同的方式实现)。此外,UML图显示了一种对称性,我想用OOP方法来防止这种对称性,因为OOP是为了防止重复的代码/对称性,对吗


那么,什么是最好的设计?还是两个选项都不好?

你是否考虑过使用泛型来实现数据类型?AbstractCalculationType,其中DataType1扩展了DataType,因此您可以获得CalcType1A扩展AbstractCalculationType的实例,并且您不会遇到强制转换问题。使用泛型解决了这个问题!谢谢!
public class CalcType1A extends AbstractCalculationType
{
/* ... */

private DataType1 data;

public float calcSingleResult(AbstractDataObject data)
{
    this.data = (DataType1) data;
}

/* ... */
}
public class CalculationStrategy1 extends AbstractCalculationStrategy
{
/* ... */

private DataGatherer1 dataGatherer1;
private List<AbstractCalculationType1> calculators; 

public float calcAllResult(int value)
{
    List<Float> result = new List<Float>();
    DataType1 dt1 = dataGatherer1.getData(value);
    for (int i = 0; i < calculators.size(); i++)
    {
        result.add(calculators.get(i).calcSingleResult(dt1));
    }
}

/* ... */
}