Java 工厂内的If语句太多
我目前正在开发一个具有许多不同设计模式的应用程序。它需要遵循良好的实践,基本上没有代码气味 我使用工厂方法打印随机类型的对象,但我必须使用3个if语句,这似乎效率低下。。。如果我想打印出10个不同的对象,会发生什么?如果没有其他方法可以解决这个问题的话,我们只需要添加更多的语句 **在工厂中,这种特殊方法的最终用途是只返回一个ball类型的随机对象(1)Java 工厂内的If语句太多,java,c++,refactoring,factory,Java,C++,Refactoring,Factory,我目前正在开发一个具有许多不同设计模式的应用程序。它需要遵循良好的实践,基本上没有代码气味 我使用工厂方法打印随机类型的对象,但我必须使用3个if语句,这似乎效率低下。。。如果我想打印出10个不同的对象,会发生什么?如果没有其他方法可以解决这个问题的话,我们只需要添加更多的语句 **在工厂中,这种特殊方法的最终用途是只返回一个ball类型的随机对象(1) RandomGenerator ranGen = new RandomGenerator(); int randomNumber = ranG
RandomGenerator ranGen = new RandomGenerator();
int randomNumber = ranGen.createRandomNumber(1,3);
if(randomNumber == 1){
//return smallBall
}
else if(randomNumber ==2){
//return mediumBall
}
else if(randomNumber == 3){
//return largeBall
}
最简单的解决方案是使用
switch
语句,类似于:
int randomNumber = ranGen.createRandomNumber(1,3);
switch (randomNumber) {
case 1:
// return smallBall
break;
case 2:
// return mediumBall
break;
case 3:
// return largeBall
break;
default:
// handle non-expected value
break;
}
最简单的解决方案是使用
switch
语句,类似于:
int randomNumber = ranGen.createRandomNumber(1,3);
switch (randomNumber) {
case 1:
// return smallBall
break;
case 2:
// return mediumBall
break;
case 3:
// return largeBall
break;
default:
// handle non-expected value
break;
}
您可以使用
Map
,类似这样的东西(假设SmallBall
和其他是Ball
的子类):
Map balls=newhashmap();
放(1,新的小球());
球。推杆(2,新MediumBall());
球。推杆(3,新的大球());
RandomGenerator ranGen=新的RandomGenerator();
整数randomNumber=ranGen.createRandomNumber(1,balls.size());
返回球。获取(随机数);
注意:在本例中,factory方法将始终返回对的引用
作为三个实例之一,不会创建新对象
如果需要多个唯一实例,请在地图中放置混凝土球工厂:
Map<Integer, BallFactory> ballFactories = new HashMap<Integer, BallFactory>();
ballFactories.put(1, new SmallBallFactory());
ballFactories.put(2, new MediumBallFactory());
ballFactories.put(3, new LargeBallFactory());
RandomGenerator ranGen = new RandomGenerator();
Integer randomNumber = ranGen.createRandomNumber(1, balls.size());
return ballFactories.get(randomNumber).createBall();
Map=newhashmap();
BallFactorys.put(1,新的SmallBallFactory());
BallFactorys.put(2,新MediumBallFactory());
球工厂。放置(3,新的大型球工厂());
RandomGenerator ranGen=新的RandomGenerator();
整数randomNumber=ranGen.createRandomNumber(1,balls.size());
返回BallFactorys.get(randomNumber).createBall();
您可以使用地图
,类似这样的东西(假设SmallBall
和其他是Ball
的子类):
Map balls=newhashmap();
放(1,新的小球());
球。推杆(2,新MediumBall());
球。推杆(3,新的大球());
RandomGenerator ranGen=新的RandomGenerator();
整数randomNumber=ranGen.createRandomNumber(1,balls.size());
返回球。获取(随机数);
注意:在本例中,factory方法将始终返回对的引用
作为三个实例之一,不会创建新对象
如果需要多个唯一实例,请在地图中放置混凝土球工厂:
Map<Integer, BallFactory> ballFactories = new HashMap<Integer, BallFactory>();
ballFactories.put(1, new SmallBallFactory());
ballFactories.put(2, new MediumBallFactory());
ballFactories.put(3, new LargeBallFactory());
RandomGenerator ranGen = new RandomGenerator();
Integer randomNumber = ranGen.createRandomNumber(1, balls.size());
return ballFactories.get(randomNumber).createBall();
Map=newhashmap();
BallFactorys.put(1,新的SmallBallFactory());
BallFactorys.put(2,新MediumBallFactory());
球工厂。放置(3,新的大型球工厂());
RandomGenerator ranGen=新的RandomGenerator();
整数randomNumber=ranGen.createRandomNumber(1,balls.size());
返回BallFactorys.get(randomNumber).createBall();
您至少可以使用两种可能的技术来随机生成对象,而无需硬编码一组固定的备选方案:
interface Builder<T> {
T createObject();
}
class Factory<T> {
private final List<Builder<? extends T>> builders = new ArrayList<>();
private final RandomGenerator ranGen = new RandomGenerator();
T createRandomObject() {
int randomNumber = ranGen.createRandomNumber(0, builders.size() - 1);
return builders.get(randomNumber).createObject();
}
// Not shown: mechanisms for managing the available Builder objects
}
接口生成器{
T createObject();
}
阶级工厂{
private final List您至少有两种可能的技术可用于随机生成对象,而无需硬编码一组固定的备选方案:
建造商/工厂方法参数的随机化,以及
使用从工厂维护的此类对象集合中随机选择的生成器对象
我将关注后者。建议从一组预构建的元素中返回一个随机元素是一种特殊情况,其中构建器对象提供自己作为生成的对象。更一般的形式可能类似于:
interface Builder<T> {
T createObject();
}
class Factory<T> {
private final List<Builder<? extends T>> builders = new ArrayList<>();
private final RandomGenerator ranGen = new RandomGenerator();
T createRandomObject() {
int randomNumber = ranGen.createRandomNumber(0, builders.size() - 1);
return builders.get(randomNumber).createObject();
}
// Not shown: mechanisms for managing the available Builder objects
}
接口生成器{
T createObject();
}
阶级工厂{
私人最终列表另一种方法是应用
在下面的示例中,我们有一个名为RandomBallFactory
的类
通过克隆已注册原型创建随机(唯一)Ball
实例
优点:
- 我们可以添加新的
Ball
子类,而无需更改RandomBallFactory
实现
- 我们可以创建相同类型但参数不同的对象
- 我们没有if语句
Java示例:
import java.util.*;
abstract class Ball implements Cloneable {
abstract String getName();
public Ball clone() {
Ball ball;
try {
ball = (Ball)super.clone();
} catch (CloneNotSupportedException e) {
ball = null;
}
return ball;
}
}
class SmallBall extends Ball {
public String getName() { return "smallBall"; }
}
class MediumBall extends Ball {
public String getName() { return "mediumBall"; }
}
class LargeBall extends Ball {
public String getName() { return "largeBall"; }
}
class RandomBallFactory {
private final List<Ball> prototypes;
public RandomBallFactory() {
prototypes = new ArrayList<Ball>();
}
public void registerBall(Ball ball) {
prototypes.add(ball);
}
public Ball createBall() {
Random randomGenerator = new Random();
Integer randomNumber = randomGenerator.nextInt(prototypes.size());
return prototypes.get(randomNumber).clone();
}
}
public class TestBalls {
public static void main(String[] args) {
RandomBallFactory randomBallFactory = new RandomBallFactory();
randomBallFactory.registerBall(new SmallBall());
randomBallFactory.registerBall(new MediumBall());
randomBallFactory.registerBall(new LargeBall());
Ball ball = randomBallFactory.createBall();
System.out.println(ball.getName());
}
}
#include <iostream>
#include <vector>
#include <memory>
#include <cstdlib>
#include <ctime>
class Ball {
public:
Ball() { std::cout << __func__ << std::endl; }
Ball(Ball& other) { std::cout << __func__ << " copy from " << other.getName() << std::endl; }
virtual ~Ball() { std::cout << __func__ << std::endl; }
virtual std::string getName() = 0;
virtual Ball* clone() = 0;
};
class SmallBall : public Ball {
public:
std::string getName() { return "smallBall"; }
Ball* clone() { return new SmallBall(*this); }
};
class MediumBall : public Ball {
public:
std::string getName() { return "mediumBall"; }
Ball* clone() { return new MediumBall(*this); }
};
class LargeBall : public Ball {
public:
std::string getName() { return "largeBall"; }
Ball* clone() { return new LargeBall(*this); }
};
class RandomBallFactory {
private:
std::vector<std::shared_ptr<Ball> > prototypes;
public:
void registerBall(std::shared_ptr<Ball> ball_ptr) {
prototypes.push_back(ball_ptr);
}
std::shared_ptr<Ball> createBall() {
int randomNumber = std::rand() % prototypes.size();
return std::shared_ptr<Ball>(prototypes.at(randomNumber)->clone());
}
};
int main(void) {
std::srand(std::time(0));
RandomBallFactory randomBallFactory;
std::shared_ptr<Ball> sb_ptr(std::make_shared<SmallBall>());
std::shared_ptr<Ball> mb_ptr(std::make_shared<MediumBall>());
std::shared_ptr<Ball> lb_ptr(std::make_shared<LargeBall>());
randomBallFactory.registerBall(sb_ptr);
randomBallFactory.registerBall(mb_ptr);
randomBallFactory.registerBall(lb_ptr);
std::shared_ptr<Ball> ball_ptr(randomBallFactory.createBall());
std::cout << "random Ball is: " << ball_ptr->getName() << std::endl;
}
import java.util.*;
抽象类Ball实现了Cloneable{
抽象字符串getName();
公共球克隆(){
球;
试一试{
ball=(ball)super.clone();
}捕获(CloneNotSupportedException e){
ball=null;
}
回球;
}
}
类SmallBall扩展了Ball{
公共字符串getName(){返回“smallBall”;}
}
MediumBall类扩展球{
公共字符串getName(){return“mediumBall”;}
}
类LargeBall扩展了Ball{
公共字符串getName(){return“largeBall”;}
}
钢球厂{
私人最终清单原型;
公共工厂(){
原型=新的ArrayList();
}
公共无效登记球(球){
原型。添加(球);
}
公共球createBall(){
Random randomGenerator=新的Random();
整数randomNumber=randomGenerator.nextInt(prototype.size());
返回原型.get(randomNumber).clone();
}
}
公共类测试球{
公共静态void main(字符串[]args){
RandomBallFactory RandomBallFactory=新的RandomBallFactory();
randomBallFactory.registerBall(新的SmallBall());
randomBallFactory.registerBall(新MediumBall());
randomBallFactory.registerBall(新的LargeBall());