首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OO设计发布接口和类

OO设计发布接口和类
EN

Stack Overflow用户
提问于 2015-08-06 03:24:02
回答 4查看 99关注 0票数 2

目前我正在设计一个纸面上的应用程序,我在设计方面有点问题。

该应用程序的目标是,我有汽车工厂,可以给我他们的汽车模型的蓝图。蓝图不是汽车,但它描述了可以由它制造的最终汽车,例如,型号名称,车辆上的选项,如空调等。

为此,我创建了一个接口ICarBlueprint。例如,此接口上的方法可以包括getModelName()getOptionList()。这些方法必须适用于汽车蓝图的每个实例,无论是欧宝还是大众汽车蓝图。

一家工厂,例如欧宝或大众,可以给出他们的汽车蓝图清单。因此,我为工厂创建了一个接口ICarFactory。该接口包含返回ICarBluePrint对象的List的方法getAllBlueprints()。对于欧宝工厂,这将是实现接口ICarBlueprintOpelBlueprint实例。

在我的主程序中,我希望获得用户可以从中挑选的所有可能的汽车蓝图。一个例子可以是:

代码语言:javascript
复制
for(ICarFactory f : factories)
    allblueprints.addAll(f.getAllBlueprints());

然后我想要迭代这个列表,如果其中一个蓝图是我想要的车,我想要建造它。但是,汽车蓝图只能由生成此蓝图的工厂来构建。因此,欧宝汽车的蓝图只能由实现接口ICarFactoryOpelFactory实例构建。

构建一辆汽车将产生一个实际的汽车对象。为此,我创建了接口ICar。同样,对于每个工厂,我都会有实现此接口的类。

我的设计问题是从这里开始的。

要构建蓝图,我可以向ICarFactory接口添加一个名为build()的方法。然后,主程序可以简单地选择一个汽车实例,例如goodcarBlueprint,并要求汽车工厂来构建它。

因此,为了确保蓝图是由正确的工厂构建的,我考虑向接口ICarBlueprint添加一个方法getFactory(),向ICarFactory接口添加build()。这将允许我在其各自的工厂中构建一个蓝图,如下所示:

代码语言:javascript
复制
ICarBlueprint goodcarBlueprint = // Assigned somewhere else
ICar x = goodcarBlueprint.getFactory().build(goodcarBluePrint);

然而,我的直觉告诉我,这个设计真的很糟糕。任何关于正确的设计方法的帮助,我们都将不胜感激。

EN

回答 4

Stack Overflow用户

发布于 2015-08-06 03:33:54

这是非常主观的,我理解这种糟糕的设计感觉,但我不会说你的想法是“真的很糟糕”。

对我来说,这听起来像是一个经典的Builder design pattern。在这种情况下,Blueprint就是Builder。大多数生成器都有一个.build()方法。通过在Blueprint上调用.build(),您可以避免从工厂检索Blueprint,只需使用它提供给您的Blueprint再次调用工厂。蓝图仍然需要知道它自己的工厂,这样它才能让工厂制造汽车。

票数 2
EN

Stack Overflow用户

发布于 2015-08-06 04:09:05

我要避免的是ICarBlueprintICarFactory互相了解。这种紧密的耦合将使未来的变化复杂化,因为您可能会有多个工厂来构建相同的汽车蓝图。松散耦合开启了可能性。

代码语言:javascript
复制
public interface ICarBuilder {
    ICarBlueprint getBlueprint();
    ICar build();
}

public class CarBuilder implements ICarBuilder {
    private final ICarBlueprint blueprint;
    private final Collection<ICarFactory> factories = new ArrayList<ICarFactory>();

    public CarBuilder(ICarBlueprint blueprint) {
        this.blueprint = blueprint;
    }

    public ICarBlueprint getBlueprint() {
        return blueprint;
    }

    public CarBuilder addFactory(ICarFactory factory) {
        factories.add(factory);
        return this;
    }

    public ICar build() {
        // Choose least busy or least cost factory, etc. from factories.
        ICarFactory factory = ...;
        return factory.build(blueprint);
    }
}

现在,您可以创建一个ICarBuilder集合并向用户显示蓝图,然后让CarBuilder决定使用哪个工厂来生产所选的汽车。您甚至可以添加逻辑,根据交付时间和成本向用户显示工厂选项,并让他们进行选择。

票数 2
EN

Stack Overflow用户

发布于 2015-08-06 03:33:45

我认为你的设计很好。这行代码:

代码语言:javascript
复制
ICar x = goodcarBlueprint.getFactory().build(goodcarBluePrint);

有点冗长,您可能不喜欢goodcarBluePrintFactory在其中出现两次的事实。有一个简单的解决方案,保留您的设计,并将此静态助手函数添加到ICarFactory中:

代码语言:javascript
复制
public static ICar build( ICarBlueprint blueprint) {
  return blueprint.getFactory().build(blueprint);
}

当你想根据蓝图造一辆车时,你只需要:

代码语言:javascript
复制
ICar x = ICarFactory.build(goodcarBluePrint);

或者,您可以改为向ICarBlueprint添加一个build方法:

代码语言:javascript
复制
public Icar build() {
  getFactory().build(this);
}    

您可以将其用作:

代码语言:javascript
复制
ICar x = goodcarBlueprint.build();

我想我更喜欢最后一个。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31841124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档