在Java中实现工厂模式的最佳方法
我正在尝试编写工厂模式以在程序中创建MainMode或TestMode。我以前用来创建这些对象的代码是:
play = (isMode) ? new MainMode(numberRanges, numberOfGuesses) : new TestMode(numberRanges, numberOfGuesses, randNo());
我的游戏(游戏)将根据布尔值(isMode)创建MainMode对象或TestMode对象。如您所见,我正在向我的TestMode对象(randNo())添加一个额外的值。在TestMode中使用此值,以允许用户输入自己的“随机数”,而在MainMode构造函数中,则是随机生成的。在此程序中,MainMode和TestMode都是抽象类Game的子类。
现在,我想用工厂模式替换此行,尽管我不确定,因为我的TestMode构造函数需要一个额外的对象,而且我不确定需要在哪里传递此值。如果要创建Factory,则需要将其放在一个新类中,该类可能名为GameFactory或ModeFactory或类似的名称。
我将如何处理?
这里的问题是上面的代码在我的GUI中,其中numberRanges,numberOfGuesses和randNo()方法的值是。我想创建一个Factory类,但是由于randNo()激活了自己,所以无法传递这些值。这是我的randNo()方法。
private int randNo() { boolean isValidNumber = true;
int testRandomNum = 0;
while(isValidNumber) {
try {
testRandomNum = Integer.parseInt(JOptionPane.showInputDialog("Enter Random Number"));
isValidNumber = false;
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(null, "Sorry, but the number you entered was invalid");
}
}
return testRandomNum;
}
问题是,每当我传递randNo()时,它就会显示JOptionPane。就像我已经说过的,GUI和逻辑是分开的。GUI位于GUI程序包中,而其余代码位于逻辑程序包中。
回答:
请注意,其他一些答案可能可以描述工厂,但不能描述 GOF Factory Pattern 。
现在,我想用工厂模式替换此行,尽管我不确定,因为我的TestMode构造函数需要一个额外的对象,而且我不确定需要在哪里传递此值。
好吧,您可以这样想:MainMode(而不是TestMode)是一种执行特殊操作的程序。它要做的特殊事情是 忽略
给定的数字,以确保它确实是随机的。通过这种思考方式,MainMode可以做更多的事情。
或者,如果除了随机性之外,MainMode和TestMode没有不同,那么您可能会认为可以将相似性分解为一个类,这是计算随机数的两种策略之一。一种策略实际上是随机的,而另一种则是错误的,其随机范围仅为1个值。
但让我们假设MainMode和TestMode之间还有其他区别-大概是TestMode将额外的调试输出到System.out或其他东西。
我们仍然可以从测试或玩游戏中排除“我们如何提供随机性”。这些都是 正交的 问题。
因此,现在我们知道,除了“模式”所做的一切之外,它还应该接受随机性策略。然后,例如,当您被告知标准平台随机性还不够真正随机时,您可以使用更好的随机性来代替它。
或者,您可以进行测试,其中将随机范围限制为仅两个选择,或者始终从一到零交替,或者在每次调用时返回某个Vecrtor或Iterator中的下一个值。
因此,我们使用GOF策略模式来构建随机性策略:
interface RandomStrategy { public double random();
}
public class NotSoRandom implements RandomStrategy {
private double r;
public NotSoRandom( final double r ) { this.r = r; }
public double random() { return r; }
}
public class PlatformRandom implements RandomStrategy {
public double random() { return Math.random(); }
}
现在,如果您的整个应用仅创建了一个“模式”,则无需工厂。当您需要一遍又一遍地创建相同的类类型时,可以使用工厂;实际上,工厂只是用于创建正确种类的(子)类的策略。
在生产代码中,我曾使用过一些工厂,这些工厂中有一些通用类可以创建东西,并且我需要告诉如何创建正确的子类来创建。我经过一家工厂。
现在,我们为“模式”创建工厂模式;这将令人惊讶地类似于“策略”模式:
abstract class Mode() { private RandomStrategy r;
public Mode( final RandomStrategy r ) { this.r = r; }
// ... all the methods a Mode has
}
public class MainMode implements Mode {
public MainMode( final RandomStrategy r ) { super(r); }
}
public class TestMode implements Mode {
public TestMode( final RandomStrategy r ) { super(r); }
}
interface ModeFactory{
public Mode createMode( final RandomStrategy r );
}
public class MainFactory() {
public Mode createMode( final RandomStrategy r ) {
return new MainMode(r);
}
}
public class TestFactory() {
public Mode createMode( final RandomStrategy r ) {
return new TestMode(r);
}
}
现在,您了解了工厂模式和策略模式,以及它们在“形状”方面的相似之处,但在用法上却有所不同:工厂模式是对象创建的,它返回要使用的对象;策略是对象行为的,通常会显式创建一个实例,并保留对该实例的引用以封装算法。但是就结构而言,它们非常相似。
编辑:OP在评论中询问“如何将其集成到我的GUI中?”
好吧,除了“模式”,所有这些都不属于程序的GUI。您将创建ConcreteStrategy,然后在某些设置例程中将其传递给首选的Factory,并可能根据命令行参数或配置文件确定要使用哪个。基本上,您会在选择原始帖子中的正确类别时非常选择正确的工厂。
再说一次,如果您只创建其中之一,则不需要Factory。 工厂用于批量生产(或创建相关具体类型的族,尽管这超出了此问题的范围)。
(假设我们有一个游戏,用户可以在命令行上选择是与机器人还是与龙搏斗;然后我们要实例化一个产生对手(接口)的OpponentFactory,并派生类RobotOpponent和DragonOpponent,并传递该工厂游戏中会生成NewOpponent()的部分。类似地,用户可能会选择勇敢或怯ward的对手(我们将其设置为策略)。我们不需要制作更多的策略实例,因为策略通常是幂等的(无状态和单例)。)
static int main( String[] args ) {// setup game world
final RandomStrategy r = "random".equals(args[0])
? new PlatformRandom() : new NotSoRandom( Integer.intValue(args[0]) ) ;
// notice the simlarity to the code you originally posted;
// we factored out how to achieve "randomness" as a Strategy.
// now we will use our Strategy to setup our Factory;
final ModeFactory f = "test".equals(args[1])
? new TestFactory(r) : new MainFactory(r);
// also similar to your code
// we've just added an extra level of indirection:
// instead of creating a Mode, we've created an object that can create Modes
// of the right derived type, on demand.
// call something that uses our factory
functionThatRunsameAndNeedstoProduceModesWhenevertNeedsTo( f );
}
以上是 在Java中实现工厂模式的最佳方法 的全部内容, 来源链接: utcz.com/qa/410878.html