我刚刚阅读了一些旧的oo设计书籍和我不太关注的东西。
如果我使用类似于存储库模式的东西可以说。
即:
interface ICarRepository {
IEnumerable<car> GetCarCollection();
}
class MsSqlCarRepository : ICarRepository {
IEnumerable<car> GetCarcollection(){ ................ };
}
class car {
int CarId;
string CarName;
}
上面的代码大致是c#但并不真正相关。
虽然上述效果很好并且是我通常看到和使用的内容,但我读到的所有书籍oo通常都说明一个对象将其方法和属性结合起来。
因此忽略界面部分不应该更符合以下几行:
class car {
int CarId;
string CarName;
IEnumerable<car> GetCarcollection(){ ................ };
}
????
答案 0 :(得分:3)
所有这些都是关于代码不同部分的层之间的耦合。将域模型与可在这些域模型上执行的操作/合同分离,可以在其他上下文中更轻松地重用这些域模型。想象一下,例如有人想要使用此Car模型定义一些其他操作,而不是GetCarcollection
。在这种情况下,他会编写一个不同的存储库接口,您不需要修改此域模型。另一方面,如果您在Car对象中定义了GetCarcollection
方法,那么该模型的其他消费者将不会高兴,因为他可能不关心您的方法,但是想要使用他自己的方法。
答案 1 :(得分:1)
我们的想法是,您可以替换不同的存储库,例如PostgresSQLCarRepository,而无需更改您的Car类。
您可以使用此方法将存储库类分离到单独的库中,然后通过依赖注入加载它们。
因此,如果您编译了多个libary dll,一个与postgres对话,一个与mssql对话,一个与XML对话,您可以将其中任何一个与代码一起使用,而无需担心重新编译您的汽车类。
- 评论后编辑
在附加评论之后,问题似乎更多为什么这个真正的wolrd设计模式似乎不符合OO的基本原则?
简短的回答是它遵循OO的基本原则。
答案很长......
OO的基本思想(这是过于简单化而不会进入大量的继承,多态等)是您将关于特定实体的属性集合和对特定实体进行操作的方法组合在一起类。
GetCarCollection()方法不适用于单个汽车实例。它适用于存储库,因为您要求存储库返回一组汽车。但是,像Start()这样的方法可能是针对汽车的方法,因为它会专门应用于那个汽车实例。
除此之外,您还拥有可以只读的属性,并且通常隐藏支持字段只能访问类实例本身,因此您可能有
public class car {
private int _carId;
private string _carName;
private int speed=0;
public Car(int carId) {
this._carId=carId;
}
public int CarId {
get { return this._carId; }
}
public string CarName {
get { return this._carName; }
set { this._carName=value; }
}
public int Speed {
get { return this._speed; }
}
public void Accelerate() {
if (this._speed<91) this._speed++;
}
}
public class MsSqlCarRepository : ICarRepository {
public MsSqlCarRepository(SqlConnection conn) {.....}
IEnumerable<car> GetCarcollection(){ ................ }
}
public class XmlCarRepository : ICarRepository {
public XmlCarRepository(string FileName) {.....}
IEnumerable<car> GetCarcollection(){ ................ }
}
你给出的例子可能对你来说似乎没有OO,但更多的是因为它过于简单化了。随着对象的详细程度和复杂程度的提高,您应该看到这实际上是一种OO方法,并开始偏离您的C struct和manager方法。
答案 2 :(得分:0)
'汽车收藏'不是汽车的固有属性。车库或停车场可能有汽车收藏。
答案 3 :(得分:0)
汽车不是汽车库。否则你需要一辆车开车。
GetCarCollection 可以是一个静态方法,但那时不允许你模拟或注入存储库,并且不代表关注点的分离(即类型的角色是否为< em>代表一辆车?还是获取汽车?)。
这里划线的位置是主观的,可能因项目要求而异。