我昨天接受了一次采访,问了一个问题:
赛车商店系统:
该系统存储有关可供玩家使用的汽车的信息。
设计一个可以生产玩家要求的汽车的系统(如果玩家想要一辆手动换挡、燃烧柴油的汽车,你的系统应该提供一辆符合要求的汽车实例),系统应该具有良好的可扩展性和可运维性。
我的想法和解决方案:
我的想法是需求包含两个属性:齿轮和燃料。我计划制作一个抽象类包含属性和相应的行为。考虑到可扩展性,将有一个接口Moable
,其中包含汽车可以做的行为。
如果将来添加任何新属性,要么创建一个包含新属性的新抽象类,要么将该属性添加到现有的抽象类中,如果需要新的行为,我将创建新接口或将行为添加到现有接口中。
这是我所做的:一个接口包含一般行为,目前只有show Specs()
。
public interface Movable {
public String showSpecs();
}
抽象类包含属性< code>fuel和< code>gear
public abstract class Car implements Movable {
String gear;
String fuel;
abstract void setFuel(String fuel);
abstract String getFuel();
abstract void setGear(String gear);
abstract String getGear();
}
现在赛车类实现:
public class RaceCar extends Car {
public RaceCar(String fuel, String gear) {
this.fuel = fuel;
this.gear = gear;
}
public void setFuel(String fuel) {
this.fuel = fuel;
}
public String getFuel() {
return this.fuel;
}
public void setGear(String gear) {
this.gear = gear;
}
public String getGear() {
return this.gear;
}
public String showSpecs() {
StringBuilder sb = new StringBuilder();
sb.append("Gear:").append(this.gear);
sb.append("Fuel:").append(this.fuel);
return sb.toString();
}
}
以下是我拥有的主要类:
public class Main {
public static void main(String[] args) {
System.out.println("get started...");
Car car = new RaceCar("diseal", "automatic");
System.out.println(car.showSpecs());
}
}
面试官回答说,我提供的解决方案不可扩展,难以维护,但没有提供细节,所以我仍然对我犯了什么错误以及如何改进它感到困惑。
有人能帮助分享你的想法并指出我应该改进什么吗?
谢谢!
我会用两个类来回答这个问题,即< code>Car和< code>CarBuilder:
public final class Car {
private final Fuel fuel;
private final Gears gears;
public Car(Fuel fuel, Gears gears) {
this.fuel = fuel;
this.gears = gears;
}
public Fuel getFuel() {
return fuel;
}
public Gears getGears() {
return gears;
}
enum Fuel {
GASOLINE,
DEISEL
}
enum Gears {
AUTOMATIC,
MANUAL
}
}
public class CarBuilder {
//sensible defaults:
private Car.Fuel fuel = Car.Fuel.GASOLINE;
private Car.Gears gears = Car.Gears.MANUAL;
public CarBuilder() {
}
public CarBuilder withFuelType(Car.Fuel fuel) {
this.fuel = fuel;
return this;
}
public CarBuilder withGearBox(Car.Gears gears) {
this.gears = gears;
return this;
}
public Car build() {
return new Car(this.fuel, this.gears);
}
}
Car
是不可变的,还包含表示其内部状态所需的枚举,因此这些属性不能从它们有意义的上下文/对象中泄露出去,因此将来更容易维护。
构建器类虽然是当前形式的基本类,但可以扩展以适应更复杂的构造要求,而不会将实现细节泄漏到Car
类中。
默认值是可选的,但可能有意义。
汽车可以这样构造:
//Default car:
Car car = new CarBuilder().build();
//Customised car:
Car car = new CarBuilder().withFuelType(Car.Fuel.DEISEL).withGearBox(Car.Gears.AUTOMATIC).build();
我想,当他提到可伸缩和可维护时,他可能期待的是可插入类之类的东西。所以我认为这种策略模式是意料之中的。如果期望传输或注入做一些真正的逻辑,我可以假设它们是行为而不仅仅是状态。因此导致了这种实现。
public interface TransmissionPolicy {
public void transmit();
}
public class AutomaticTransmission implements TransmissionPolicy {
public void transmit() {
//do some real logic here
print("automatic...");
}
}
public class ManualTransmission implements TransmissionPolicy {
public void transmit() {
print("we love it..."); //just an example of really simple logic
}
}
public interface InjectionPolicy {
public void inject();
}
public class DieselInjection implements InjectionPolicy {
public void inject() {
print("diesel");
}
}
public class GasolineInjection implements InjectionPolicy {
public void inject() {
print("gasoline...");
}
}
public class Car {
public void make(TransmissionPolicy transmission, InjectionPolicy injection) {
//set other parts
transmission.transmit();
//set other parts
injection.inject();
//other parts
}
}
//--------------somewhere in some clients client --------------------
Car car = new Car();
//actually, to be really configurable use a factory method here.
car.make(new ManualTransmission(), new GasolineInjection());
如果这是预期的,那么只有lambdas或命令模式也会被制造出来。