- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
场景
我正在用 Java 编写一个涉及汽车的程序。
注意:我已(尽我所能)简化了此场景,使其更通用且更易于理解。我实际上并不是在研究汽车。
我创建了一个 Cars
类,它是 Car
对象的集合。
Car
对象有一个 speed
(double) 和一个 year
(int)。构造函数将年份作为参数,例如:
public class Car {
private int year;
private double speed;
public Car(int year) {
this.year = year;
}
}
这是棘手的部分……汽车必须有一个种类(比如 Corvette 或 Clunker)。 Corvette 的 speed
为 0.9
,而 Clunker 的 speed
为 0.1
。 Car
永远不能在不指定它应该是哪种汽车的情况下被实例化。所以现在,要制造一辆汽车,我们有:
Car car = new Car(1998, Corvette);
我们刚刚创建的 Corvette 将是 Car
对象,speed
为 0.9
。
问题
我的实际情况涉及更多种类的汽车,每辆汽车除了speed
之外还有几个特定的属性(也许还有color
,numDoors<的字段
和 fuelTankSize
)。有这么多种类的汽车(每一种都有自己的特定属性),代码变得比我想要的更复杂。
可能的解决方案
我可以使用子类,也就是说,有一个由 Corvette
和 Clunker
扩展的抽象 Car
类,但是然后我遇到了使用 Cars
对象的问题(因为我无法收集无法实例化的东西)。 请参阅下面的编辑。
使用枚举(例如 CarKind
)似乎需要几个凌乱的 switch 语句:
speed
字段Cars
类创建 Car
对象您可以如何提供帮助
我正在寻找一种解决方案,允许单个 Cars
类包含每个 Car
对象。我不想要不同的 Collection (例如Corvettes
、Clunkers
)。我也在寻找一种解决方案,允许根据单个汽车种类的属性创建 Car
对象...如前所述,创建一个新的 Car
kind Corvette
将导致 speed
为 0.9
。应该没有其他方法可以指定汽车的速度
。
在这种情况下是否有最佳实践?我举的例子够清楚了吗?
谢谢。
编辑:我不想要抽象 Car
对象集合的原因是 Cars
集合的目的是创建和操作 Car
对象,无论其种类如何。 Car
是抽象的似乎使这个复杂化。如果您认为这是最佳解决方案,请做出相应的回答。
最佳答案
I'm looking for a solution that allows a single Cars class to contain every Car object. I don't want different collections (like Corvettes, Clunkers). I'm also looking for a solution that allows the creation of Car objects based on the attributes of an individual car kind... as previously mentioned, creating a new Car of kind Corvette would result in a speed of 0.9. There should be no other way to specify a car's speed.
天哪,天哪,解决这个问题的方法太多了,我们可以继续一整天!我会做一个大脑转储,希望它不会对你来说太难处理。
解决方案 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";
}
}
现在,您可以将策略传递给您的汽车制造商。
public class Car{
// Variables ...
public Car(CarCreationStrategy strategy, int year){
strategy.BuildCar(this); // Implements your properties here.
this.year = year;
}
}
所以,你现在得到的真是太棒了!
List<Car> cars = new List<Car>();
cars.Add(new Car(new CorvetteStrategy(),1999));
cars.Add(new Car(new ToyotaStrategy(),2011);
这将完全按照您的意愿行事。
但是,您会在策略和汽车之间建立耦合。
解决方案 2:使用 Factory。
Factory 也是一个不错的解决方案,而且可能更容易。您要做的是拥有一个 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;
}
}
用法:
List<Car> cars = new List<Car>();
cars.Add(CarFactory.BuildCorvette(1999));
cars.Add(CarFactory.BuildToyota(2011));
所以这样做的好处是您现在不必担心实例化 Car。它全部由 CarFactory 处理,将您的“实例化逻辑”与您的代码分离。但是,您仍然需要知道要构建哪辆车并相应地调用该方法,这仍然是一个小耦合。
方案三:策略工厂!
因此,如果我们想摆脱最后一点耦合,就让我们将两者结合起来吧!
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);
现在您有了一个制造汽车的策略,一个为您制造汽车的工厂,以及一辆没有您原来的额外耦合器的汽车。很棒,不是吗?
如果您使用过 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";
}
}
使用它可以让您灵活地动态创建 AbstractStrategies(例如,从数据存储中提取汽车属性)。
关于java - 抽象类的集合(或类似的东西......),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7493438/
学习SQL。有一个简单的带有字段标题的桌面游戏。我想根据标题进行搜索。如果我有一款名为 Age of Empires III: Dynasties 的游戏,并且我使用 LIKE 和参数 Age of
我正在尝试为以下数据结构创建镜头。我正在使用lens-family . data Tree = Tree { _text :: String, _subtrees ::
我发现很难理解这一点。比如说,在 Python 中,如果我想要一个根据用户输入在循环中修改的列表,我会有这样的内容: def do_something(): x = [] while(
我有一个像这样的 mysql 查询 SELECT group_name FROM t_groups WHERE group_name LIKE '%PCB%'; 结果是 group_name ----
我的数据库表中有超过一百万条记录。当我使用like时非常慢,当我使用match against时他们丢失了一些记录。 我创建帮助表: 标签列表 tag_id tag_name tag_rel_me
我在我的一个 Java 项目中使用 JXBrowser 来简单显示 googlemaps 网页,以便我可以在那里跟踪路线,但最近我想改进该项目,但我的问题是 JXBrowser 的许可证过期(只有一个
小问题:如何将 mysql_escape_string 变量包含在 like 子句中? "SELECT * FROM table WHERE name LIKE '%". %s . "%'" 或
我尝试使用几个jquery消息插件,例如alertify . 但我注意到的主要事情是系统消息框会停止后台功能,直到用户响应。其他插件没有此功能。 有没有办法将此功能添加到 jquery 插件中?可以扩
我是 Ruby 新手。我过去使用过 shell。我正在将 shell 程序转换为 ruby。我有以下命令 cmd="cat -n " + infile + " | grep '127.0.0.1
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
当我研究 Rust 时,我试图编写一个 Rust 函数来查看任何可迭代的字符串。 我最初的尝试是 fn example_1(iter: impl Iterator); fn example_2(ite
我必须在我的项目中使用代码拆分。但无论如何,第一次初始下载有一些代码。 现在我想向最终用户展示代码下载(.cache.html - 或其他代码拆分)的进度,例如 gmail 启动进度。 请你帮帮我。
我今天找到了一个错误,它最终是由我代码中的以下片段引起的(我试图在列表中仅过滤“PRIMARY KEY”约束): (filter #(= (% :constraint_type "PRIMARY KE
我正在尝试在关键字段上实现检查约束。关键字段由 3 个字符的前缀组成,然后附加数字字符(可以手动提供,但默认是从序列中获取整数值,然后将其转换为 nvarchar)。关键字段定义为 nvarhcar(
我正在尝试使用以下方式创建 List 实例: List listOne = new ArrayList(); List listTwo = new ArrayList(){}; List listTh
我过去曾为 iOS 开发过,最近转向了 mac 开发。我开始了一个“感受”事物的项目,但遇到了一个问题。我试图创建一个 NSTableView 来显示多个项目,包括一个标签、一个 2 UIImageV
我正在尝试编写一个查询,该查询将返回哪些主机缺少某个软件: Host Software A Title1 A
AFAIK,在三种情况下别名是可以的 仅限定符或符号不同的类型可以互为别名。 struct 或 union 类型可以为包含在其中的类型设置别名。 将 T* 转换为 char* 是可以的。 (不允许相反
\s 似乎不适用于 sed 's/[\s]\+//' tempfile 当它为工作时 sed 's/[ ]\+//' tempfile 我正在尝试删除由于命令而出现在每行开头的空格: nl -s ')
我正在使用 ocamlgraph 在 ocaml 中编写程序,并想知道是否要将其移植到 F# 我有哪些选择?谢谢。 最佳答案 QuickGraph .Net 最完整的图形库之一 关于F# 图形库(类似
我是一名优秀的程序员,十分优秀!