在属性/上下文类中封装属性

时间:2012-11-07 20:51:49

标签: java

我创建了一个BicycleProducer接口,它有不同的实现:OffroadBicycleProducerFastBicycleProducer等等。

这些工厂中的每一个都需要许多参数来生产自行车。我想将这些属性封装在一个类中,并将其传递给produce方法。然而,自行车需要不同的属性 - 有些可能是相同的 - 我想知道如何正确地做到这一点。在BicycleProducer的接口中,我目前有一个名为produce的方法,它接受一个参数BicycleProducingContext,它是一个包含所有公共属性的接口。然后你有实现它的实现,并根据它的自行车类型添加necassary属性。然后你需要用produce方法投射它......但我不知道。我感觉有点狡猾(可能不是)。

这是一种很好的方法,还是应该以另一种方式进行?

public interface BicycleProducer {
    void produce(BicycleProducingContext context);
}

public class OffroadBicycleProducer implements BicycleProducer {

    public void produce(BicycleProducingContext context) {
        context = (OffroadBicycleProducingContext) context;
    }
}

public interface BicycleProducingContext {

    int numberOfBicycles();
    void brand(String brand);
}

public class OffroadBycycleProducingContext implements BicycleProducingContext {

    //..
}

1 个答案:

答案 0 :(得分:1)

我发现你提出的设计有两点尴尬:

  1. 对我来说,看起来你可能根本不需要工厂(即你的Producer课程)。当您需要构造一个在编译时未知类型的对象时,工厂非常有用。但是既然你想为每种类型的自行车设置单独的工厂类(例如OffroadBicycleProducer),我认为你确实知道你想要提前建造什么样的物体。

  2. 使用上下文类使参数传递不那么难看是一个好主意,但是如果你开始为每种类型的自行车创建单独的上下文类,那么你最终会陷入尴尬的境地,必须知道哪个上下文构造以及它需要什么数据 - 如果你有所有这些,你也可以跳过中间步骤并立即构建Bicycle

  3. 如果我认为你确实知道你需要提前构建什么样的对象,那么我不会使用工厂,而是使用构建器模式,或使用普通的旧构造函数。构造函数方法可能如下所示:

    public abstract class Bicycle {
        private int year;
        private String color;
    
        public Bicycle(BicycleProducingContext context) {
            this.year = context.getYear();
            this.color = context.getColor();
        }
    }
    
    public class OffroadBicycle extends Bicycle {
        private String terrainType;
    
        public OffroadBicycle(BicycleProducingContext context) {
            super(context);
            this.terrainType = context.getTerrainType();
        }
    }
    
    public class FastBicycle extends Bicycle {
        private int maxSpeed;
    
        public FastBicycle(BicycleProducingContext context) {
            super(context);
            this.maxSpeed = context.getMaxSpeed();
        }
    }
    

    如果您不知道在运行时要构造的Bicycle类型,那么您可以将上述方法用于单个工厂。例如:

    public class BicycleFactory {
        public static Bicycle constructBicycle(BicycleProducingContext context) {
            if (context.getBicycleType().equals("OffroadBicycle")) {
                return new OffroadBicycle(context);
            } else if (context.getBicycleType().equals("FastBicycle")) {
                return new FastBicycle(context);
            } else {
                throw new IllegalArgumentException("Encountered unrecognized Bicycle type: " + context.getBicycleType());
            }
        }
    }
    

    我希望我不会过度简化您的用例,但在我看来,上述内容应该可以实现您的目标。

相关问题