现状......
我有一个Car
界面:
interface Car {
void startWith(Key key);
void switchGearTo(GearMode mode);
//..
static Car newCar() { // factory
return new CarImpl();
}
}
(工厂存在于单独的类中,嵌套以缩短此示例)
此界面有一个实现:
class CarImpl implements Car {
private Ignition ignition;
private GearShift gearShift;
public void startWith(Key key) {
// use ignition
}
public void switchGearTo(GearMode mode) {
// use gear shift
}
}
此时,Car
足以满足应用程序的需求,因此这种结构很好。它是基于YAGNI原则创建的,因为不需要进一步的抽象,我们的要求得到满足。
问题..
应用程序的要求已更改,Car
不再具体。我们需要不同类型的汽车,例如SportsCar
;需要另一个抽象层次。
问题是,Car
已经有了直接实现,现在它应该只是一个没有实现的抽象级别。
我无法移除静态工厂,否则会破坏代码。但开发人员不再可能创建Car
的实例,因为它不再具体满足我的应用程序的需求。
我的尝试解决方案..
解决此类问题的唯一方法是进行重大重新部署。应用程序的理念发生了变化,意味着需要“重新开始”,没有其他方法可以解决这个问题。 (我真的希望事实并非如此)
我可以指定一个默认汽车,我仍然需要为默认汽车创建一个新的(描述性)方法,导致同一个类中的两个方法执行完全相同的操作(无需更改就可以伸缩)。这增加了混乱和可能的混淆,这对缩放没有帮助。
我的问题..
这是一个可以在没有重大部署的情况下解决的问题吗?如果没有,如何构建他们的代码以避免这个问题?是否有可能在仍然遵守YAGNI的同时考虑到需求的这种变化?
答案 0 :(得分:2)
如果类型实现不再有效,通常建议重新开始,有时这是唯一的解决方案。如果已定义接口,则不能仅阻止其他类实现它。
虽然您遇到了问题,但更改界面层次结构可以解决问题。由于interface Car
现在更抽象,因此创建扩展interface SportsCar
的抽象接口(interface Car
等)。此外,您有class CarImpl
来实现较少抽象的接口。
最后,只要定义了Car
接口,就无法阻止其他开发人员实例化Car
。
答案 1 :(得分:1)
factory 的重点是解决这些问题,即不允许客户端代码显式构造特定类的实例。您的工厂现在应该返回默认情况'类(如其他人所提到的)不是CarImpl的一个实例,但更专业,例如一辆轿车,或者你认为是默认汽车的任何东西。