Java 工厂内的If语句太多

Java 工厂内的If语句太多,java,c++,refactoring,factory,Java,C++,Refactoring,Factory,我目前正在开发一个具有许多不同设计模式的应用程序。它需要遵循良好的实践,基本上没有代码气味 我使用工厂方法打印随机类型的对象,但我必须使用3个if语句,这似乎效率低下。。。如果我想打印出10个不同的对象,会发生什么?如果没有其他方法可以解决这个问题的话,我们只需要添加更多的语句 **在工厂中,这种特殊方法的最终用途是只返回一个ball类型的随机对象(1) RandomGenerator ranGen = new RandomGenerator(); int randomNumber = ranG

我目前正在开发一个具有许多不同设计模式的应用程序。它需要遵循良好的实践,基本上没有代码气味

我使用工厂方法打印随机类型的对象,但我必须使用3个if语句,这似乎效率低下。。。如果我想打印出10个不同的对象,会发生什么?如果没有其他方法可以解决这个问题的话,我们只需要添加更多的语句

**在工厂中,这种特殊方法的最终用途是只返回一个ball类型的随机对象(1)

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());