这是糟糕的 oop 设计吗?
我有一个名为 Chicken 的类,在 Chicken 中我有一些方法, 因此,在我实例化并调用 Chicken 方法的另一个类中,我可能会执行以下操作:
Chicken chicken = new Chicken("Name","Description")
public void UpdateChicken(Chicken chicken)
{
chicken.Update(chicken);
}
上面的内容很好还是存在问题,如果是这样,最好使用另一个类(例如 ChickenCalculations)并执行以下操作:
public void UpdateChick(Chicken chicken)
{
ChickenCalculations.Update(chicken);
}
这里是一个实现:
Chicken chicken = new Chicken("Bob","Coolest Chicken", 4, 123, 5, 388, true, false, true);
Chicken anotherChicken = new Chicken()
anotherChicken.Update(chicken);
chicken.Update(chicken)
这是一个更实际的例子,而不是使用 Chicken:
public class AirlineBooking
{
int BookingId {get;set;}
string Name {get;set;}
string Description {get;set;}
decimal Price {get;set;}
decimal Tax {get;set;}
string seat {get;set;}
bool IsActive {get;set;}
bool IsCanceld {get;set;}
public AirlineBooking(string name, string description, decimal price,
decimal tax, string seat, bool isActive, bool isCanceled)
{
Name = name;
Description = description;
Price = price;
Tax = tax;
Seat = seat;
IsActive = isActive;
IsCanceled = isCanceled;
}
public Update(AirlineBooking airlineBooking, int id)
{
//Call stored proc here to update booking by id
}
public class BookingSystem
{
//Create new booking
AirlineBooking booking = new AirlineBooking("ticket-1",
"desc",150.2,22.0,
"22A",true, false);
//Change properties and update.
booking.Name ="ticket-2";
booking.Description = "desc2";
booking.Price = 200.52;
booking.Tax = 38.50;
public void UpdateBooking(AirlineBooking booking, int id)
{
/* This is the meat of the question, should the passed in booking to
update itself or should I have a Service Class , such as
AirlineBookingOperations with an update method. */
booking.Update(booking,id);
}
}
}
I have class called Chicken and in Chicken I have some methods,
so in another class where I instantiate and call methods on Chicken, I might do something like this:
Chicken chicken = new Chicken("Name","Description")
public void UpdateChicken(Chicken chicken)
{
chicken.Update(chicken);
}
Is the above fine or does it present problems, if so, is it better to have another class, such as ChickenCalculations and do something like:
public void UpdateChick(Chicken chicken)
{
ChickenCalculations.Update(chicken);
}
Here is an implementation:
Chicken chicken = new Chicken("Bob","Coolest Chicken", 4, 123, 5, 388, true, false, true);
Chicken anotherChicken = new Chicken()
anotherChicken.Update(chicken);
chicken.Update(chicken)
Here is a more practical example instead of using a Chicken:
public class AirlineBooking
{
int BookingId {get;set;}
string Name {get;set;}
string Description {get;set;}
decimal Price {get;set;}
decimal Tax {get;set;}
string seat {get;set;}
bool IsActive {get;set;}
bool IsCanceld {get;set;}
public AirlineBooking(string name, string description, decimal price,
decimal tax, string seat, bool isActive, bool isCanceled)
{
Name = name;
Description = description;
Price = price;
Tax = tax;
Seat = seat;
IsActive = isActive;
IsCanceled = isCanceled;
}
public Update(AirlineBooking airlineBooking, int id)
{
//Call stored proc here to update booking by id
}
public class BookingSystem
{
//Create new booking
AirlineBooking booking = new AirlineBooking("ticket-1",
"desc",150.2,22.0,
"22A",true, false);
//Change properties and update.
booking.Name ="ticket-2";
booking.Description = "desc2";
booking.Price = 200.52;
booking.Tax = 38.50;
public void UpdateBooking(AirlineBooking booking, int id)
{
/* This is the meat of the question, should the passed in booking to
update itself or should I have a Service Class , such as
AirlineBookingOperations with an update method. */
booking.Update(booking,id);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
为什么
UpdateChicken
函数不是Chicken
类的成员?这样,您就不必传入
Chicken
对象,而只是在现有实例上调用Update
方法:通常最好将在特定类上操作的所有方法封装在内部 该类,而不是将它们分成一个单独的“帮助”类。让他们鸡自己管理吧!
Why isn't the
UpdateChicken
function a member of theChicken
class?That way, you wouldn't have to pass in an instance of a
Chicken
object, but rather just call theUpdate
method on an existing instance:It's generally best to encapsulate all the methods that operate on a particular class inside of that class, rather than splitting them up into a separate "helper" class. Let them chickens manage themselves!
面向对象编程的整个思想是将对象视为能够对自身进行操作的对象。
所以你应该使用
chicken.Update()
来更新鸡。The whole idea of Object Oriented Programing is to think of objects as able to act upon themselves.
So you should just use
chicken.Update()
to update a chicken.我将使用您的
AirlineBooking
类作为示例,因为很多人似乎对Chicken
示例感到困惑。一些介绍:
单一责任原则指出一个对象应该有一个单一责任,并且它应该只关注与该责任狭隘一致的事情。例如,
TaxCalculator
应该仅负责计算税收,而不是例如转换货币 - 这是CurrencyConverter
的工作。这通常是一个非常好的主意,因为这意味着您的应用程序被构造成代码块,每个代码块都有一个职责,使其更容易理解并且更安全地进行更改。另一种表达方式是,类或模块应该有一个且仅有一个更改原因,例如“我们计算税收的方式已更改”或“我们转换货币的方式已更改”。
您需要问自己的问题是:
AirlineBooking
的责任是什么?例如,在这种情况下,我会说
AirlineBooking
的责任是“封装航空公司预订”,而更新航空公司预订实际上是预订系统的责任,而不是AirlineBooking< /代码>。
或者,考虑这个问题的另一种方式是,如果我将
Update
方法放在AirlineBooking
上,这将意味着:AirlineBooking
类。AirlineBooking
需要更改。即
AirlineBooking
现在有很多不同的原因需要更改,因此它不应该负责“更新”简而言之,我可能会这样做:
您应该问自己这些问题的原因是因为它确实取决于
AirlineBooking
在您的应用程序中的用途。例如,如果
AirlineBooking
“感知”(即引用)预订系统,那么您可以添加一个“帮助器”方法,如下所示:I'm going to use your
AirlineBooking
class as an example because a lot of people seem to have confused themselves over theChicken
example.Some introduction:
The Single responsibility principle states that an object should have a single responsibility and that it should only concern itself with things narow aligned with that responsibility. For example a
TaxCalculator
should only be responsible for calculating tax and not, for example, with converting currency - this is the job of theCurrencyConverter
.This is often a really good idea, as it means that your application is structured into chunks of code, each one with a single responsibility making it easier to understand and safer to change. Another way of putting this is that a class or module should have one and only one reason to change, for example "The way we calculate tax has changed", or "The way we convert currency has changed".
The questions you need to ask yourself are:
AirlineBooking
?For example in this case I would say that the responsibility of
AirlineBooking
is "Encapsulating an airline booking", and that updating an airline booking is in fact the responsibility of the booking system, notAirlineBooking
.Altertnaively, another way of thinking about this is that if I put the
Update
method onAirlineBooking
this would mean that:AirlineBooking
class needs to change.AirlineBooking
needs to change.I.e.
AirlineBooking
now has many different reasons to change and so it shouldn't also be responsible for "Updating"In short, I'd probably do this:
The reason why you should ask yourself these questions is because it does depends on what
AirlineBooking
is used for in your application.For example, if
AirlineBooking
is "aware" (i.e. has a reference to) the booking system then you could add a "helper" method, like this:为什么不给 Chicken 类一个方法“Update(一些参数...)”?然后,您可以通过以下方式实例化鸡
并更新:
编辑
现在您可以按以下方式使用鸡类:
Why don't you give your Chicken class a method "Update(some parameters...)"? Then, you can just instanciate a chicken by
and update by:
EDIT
And now you can use your chicken class the following way:
对象应该封装功能。应传入功能以赋予封装对象灵活性。
所以,如果你要拯救鸡,你应该传入存储库功能。如果你有鸡鸡计算,并且它们很容易发生变化,那么它也应该被传入。
请注意,在这个示例中,鸡如何能够对自身执行计算并保存自己,而无需了解如何执行计算或保存事物(毕竟,它只是一只鸡)。
Objects should encapsulate functionality. Functionality should be passed in to give the encapsulating object flexibility.
So, if you're saving the chicken, you should pass in the repository functionality. If you have chicken calculations, and they're prone to change, it should be passed in as well.
Note that how in this example the chicken is able to both perform calculations on itself and persist itself, without having any knowledge of how to perform calculations or persisting things (after all, it's only a chicken).
虽然我意识到没有
Chicken
,但您的真实对象上可能有一个Update
方法,对吗?我认为你应该尝试在语言方面引入除“更新”之外的其他内容。没有办法真正理解更新的作用。它只是更新 Chicken 中的“数据”吗?那么,什么数据呢?而且,是否应该允许您像这样更新 Chicken 实例?
我宁愿看到这样的东西
:这是一个非常有趣的 OOP 练习: http: //milano-xpug.pbworks.com/f/10080616-extreme-oop.pdf
While I realize there is no
Chicken
there might be anUpdate
method on your real object, right?I think you should try introduce something else than "update" in terms of language. There is no way to really understand what update does. Does it just update the "data" in the Chicken? In that case, what data? And also, should you be allowed to update an instance of Chicken like that?
I would rather see stuff like
Here is a pretty interesting exercise in OOP: http://milano-xpug.pbworks.com/f/10080616-extreme-oop.pdf
对于多线程环境,有一个像 ChickenCalculations 这样的单独的类更适合。当您需要执行除 Chicken.Update() 之外的其他步骤时,您可以使用 ChickenCalculations 类来执行此操作。因此,如果多个类在 Chicken 上实例化和调用方法,则不必担心 ChickenCalculations 类正在处理的相同问题。
For multithreaded environment, having a seperate class like ChickenCalculations suits better. When you need to perform few other steps besides what chicken.Update() does, you can do that with ChickenCalculations class. So if multiple classes that instantiate and call methods on Chicken does not have to worry about the same things that ChickenCalculations class is taking care of.