Pet*_*ter 7 java collections inheritance enums subclass
情景
我正在制作一个涉及汽车的Java程序.
注意:我已经简化了这种情况(尽我所能),使其更通用,更容易理解.我实际上并不是在和汽车打交道.
我创建了一个Cars类,它是一个Car对象的集合.
该Car对象有一个speed(double)和一个year(int).构造函数将year作为参数,例如:
public class Car {
private int year;
private double speed;
public Car(int year) {
this.year = year;
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个棘手的部分......汽车必须有一种(让我们说Corvette或Clunker).克尔维特将拥有speed的0.9和难有起色将有一个speed的0.1.如果Car没有指定它应该是什么样的汽车,就永远无法实例化.所以,现在,要创造一辆汽车,我们有:
Car car = new Car(1998, Corvette);
Run Code Online (Sandbox Code Playgroud)
我们刚刚创建的克尔维特将是一个Car具有对象speed的0.9.
问题
我的实际情况涉及更多种类的汽车,每辆汽车除此之外还有几个特定的属性speed(也许还有字段color,numDoors和fuelTankSize).有这么多种车(每种都有自己的特定属性),代码变得比我想要的更复杂.
可能的解决方案
我可以与子类的工作,那就是,有一个抽象Car多数民众赞成通过扩展分类Corvette和Clunker,但后来我有一个使用的问题,Cars对象(因为我不能做的东西的集合,不能被实例化).见下面的编辑.
使用枚举(例如CarKind)似乎需要几个凌乱的switch语句:
speed每辆车的领域Car从Cars类中创建对象你可以如何帮助
我正在寻找一种允许单个Cars类包含每个Car对象的解决方案.我不想要不同的集合(比如Corvettes,Clunkers).我也在寻找一个解决方案,它允许创建Car基于个人的车种...如前面提到的属性的对象,创建一个新的Car种类Corvette将导致speed的0.9.应该没有其他方法来指定汽车speed.
在这种情况下有最好的做法吗?我的例子清楚了吗?
谢谢.
编辑:我不想要抽象Car对象集合的原因是因为集合的目的是Cars创建和操作Car对象,而不管它们的种类. Car抽象似乎使这复杂化.如果您认为这是最佳解决方案,请相应地回答.
Dar*_*Teo 11
我正在寻找一个允许单个Cars类包含每个Car对象的解决方案.我不想要不同的系列(如Corvettes,Clunkers).我也在寻找一种解决方案,允许根据单个汽车类型的属性创建Car对象......如前所述,创建一辆新型Corvette汽车将导致0.9的速度.应该没有其他方法来指定汽车的速度.
哦,男孩哦,男孩有很多方法可以解决这个问题,我们可以一整天都去!我会做一次大脑转储,希望对你来说不会太多.
解决方案1:使用策略.
策略基本上是将重度可替代逻辑与另一个类分开的一种方法.在这种情况下,每辆汽车都需要以不同的方式创建.一个策略是完美的.
对不起,如果我偶然混入一些C#...自从我编写java以来已经很久了.
public interface CarCreationStrategy{
void BuildCar(Car theCar);
}
public class CorvetteStrategy implements CarCreationStrategy{
public void BuildCar(Car theCar){
theCar.Type = "Corvette";
theCar.Speed = 0.9;
theCar.Comments = "Speedster!";
}
}
public class ToyotaStrategy implements CarCreationStrategy{
public void BuildCar(Car theCar){
theCar.Type = "Toyota";
theCar.Speed = "0.5";
theCar.Comments = "Never dies, even if you drop it from the top of a building";
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以使用汽车构造函数传递策略.
public class Car{
// Variables ...
public Car(CarCreationStrategy strategy, int year){
strategy.BuildCar(this); // Implements your properties here.
this.year = year;
}
}
Run Code Online (Sandbox Code Playgroud)
所以,你现在得到的是如此棒!
List<Car> cars = new List<Car>();
cars.Add(new Car(new CorvetteStrategy(),1999));
cars.Add(new Car(new ToyotaStrategy(),2011);
Run Code Online (Sandbox Code Playgroud)
这将完全符合您的要求.
但是,您可以在战略和汽车之间找到一种耦合.
解决方案2:使用工厂.
工厂也是一个很好的解决方案,可能更容易.你做的是有一个CarFactory,有多种工厂方法来创建每种类型的汽车.
public class CarFactory{
public static Car BuildCorvette(int year){
Car car = new Car(year);
car.Type = "Corvette;
car.Speed = 0.9";
return car;
}
public static Car BuildToyota(int year){
Car car = new Car(year);
car.Type = "Toyota;
car.Speed = 0.5";
return car;
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
List<Car> cars = new List<Car>();
cars.Add(CarFactory.BuildCorvette(1999));
cars.Add(CarFactory.BuildToyota(2011));
Run Code Online (Sandbox Code Playgroud)
所以关于这一点的好处是你不必担心现在实例化汽车.它全部由CarFactory处理,将您的"实例化逻辑"与您的代码分离.但是,您仍然需要知道要构建哪辆车并相应地调用该方法,这仍然是一个小耦合.
解决方案3:战略工厂!
所以,如果我们想要摆脱最后一点的耦合,让我们将两者结合起来!
public class CarFactory{
public static Car BuildCar(CarCreationStrategy strategy, int year){
Car car = new Car(year);
strategy.BuildCar(car);
return car;
}
}
List<Car> cars = new List<Car>();
cars.Add(CarFactory.BuildCar(new CorvetteStrategy(),1999));
cars.Add(CarFactory.BuildCar(new ToyotaStrategy(),2011);
Run Code Online (Sandbox Code Playgroud)
现在你有一个建造汽车的战略,一个为你建造它们的工厂,以及一辆没有你原来的额外联轴器的汽车.很棒,不是吗?
如果您使用过Swing,您会发现这就是他们处理一些事情的方式,比如Layouts(GridBagLayout,GridLayout都是策略).还有一个BorderFactory.
起色
抽象策略
public interface CarCreationStrategy{
void BuildCar(Car theCar);
}
public class AbstractStrategy:CarCreationStrategy{
public string Type;
public double Speed;
public string Comments;
public void BuildCar(Car theCar){
theCar.Type = this.Type;
theCar.Speed = this.Speed;
theCar.Comments = this.Comments;
}
}
public class CorvetteStrategy extends AbstractStrategy{
public CorvetteStrategy(){
this.Type = "Corvette";
this.Speed = 0.9;
this.Comments = "Speedster!";
}
}
public class ToyotaStrategy extends AbstractStrategy{
public ToyotaStrategy{
this.Type = "Toyota";
this.Speed = "0.5";
this.Comments = "Never dies, even if you drop it from the top of a building";
}
}
Run Code Online (Sandbox Code Playgroud)
使用此功能,您可以灵活地动态创建AbstractStrategies(例如,从数据存储中提取汽车属性).
| 归档时间: |
|
| 查看次数: |
2777 次 |
| 最近记录: |