为什么我看不到使用 OOP 的真正意义?

发布于 2024-10-08 06:47:57 字数 1361 浏览 1 评论 0原文

可能的重复:
类。重点是什么?

我已经阅读了大量的教程,编写了许多类,使用了它们,但我仍然无法弄清楚一些 OOP 点。

我的意思是,我想我明白了这个理论。这是一种范式,一种思考和解决问题的不同方式。我知道所有的共同点:代码重用、封装、更好的错误处理、更容易的维护、继承、契约设计、更好的文档、聚合、组合、一些设计模式......

也就是说,让我们开始真正的交易。假设我有以下内容:

  • 一个数据库以及一个用于访问和查询它的类。
  • 我有一个名为 person 的表和另一个名为 address 的表
  • 简单的业务规则:一个人可以有一个或多个地址(家庭、工作、送货...),一种简单的一对多关系
  • 我有一个用于常见操作的高级类(CRUD )。每个表都有一个类,该类是该表的扩展类。
  • 当然,每个类(人员和地址)都有自己的方法:例如,getAddressByLocation 或getPersonsByAge。
  • 还有十几个视图和几个表单

所有这些都很棒并且肯定有用但是......我无法停止思考最简单的情况:列出一些人。是的,因为输出表上的每一行都是在一个类实例上生成的。我无法停止思考在未使用的资源上使用了多少内存和CPU。

列出 50 个人意味着创建 50 个实例,充满诸如 CRUD、过滤处理上传、验证规则等资源,而我需要的是运行查询并仅通过简单的循环输出结果。

这让我很困惑。不仅仅是混淆,因为我已经看到一些应用程序,当业务规则稍微复杂一点时,运行时间随着数据库呈指数级增长。

我认为,是否需要创建新的类或普通脚本来处理输出和报告?如果是,那么这意味着双重努力,一旦我需要为同一个数据库实体创建许多不同的类,那么使用 OOP 就毫无意义了。编码变得更加困难,维护变得不再酷。

我错过了什么吗?或者这是 OOP 方法的一个缺点?

我们是否应该牺牲直接、精简、更快的代码来获得更快的开发和维护?

编辑

正如预期的那样,我之前提出的一些观点误导了一些人...

首先,我对非常非常大的项目有着丰富的经验(我曾在 IBM 的 Sprint/Nextel USA 和 Directv North America 供应商工作过) ,所以我习惯于每天处理一些 TB 的数据)。

当我说从数据库中检索 50 个人时,我并不是指严格意义上的 50 个人,我只是想给出许多记录的概念。我知道 50 条记录对于今天的服务器来说根本不算什么。 5000万是。如果合适的话,想象一下最后一个数字。

Possible Duplicate:
Classes. Whats the point?

I've read tons of tutorials, wrote many classes, used them, but I still can't figure out some OOP points.

I mean, I think I got the theory. It's a paradigm, a different way to think and solve a problem. I know all commom points: code reuse, encapsulation, better error handling, easier maintenance, inheritance, design by contract, better documentation, aggregation, composition, some design patterns...

That said, let's go to the real deal. Let's say I have the following:

  • a database, and a class to access and query it.
  • I have a table named person and another table named address
  • Simple business rule: one person can have one or more address (home, work, delivery...), a simple one to many relationship
  • I have a highlevel class for commom operations (CRUD). Each table has a class that is a extension from this one.
  • Of course, each class (person and address) have their own methods: eg, getAddressByLocation or getPersonsByAge.
  • Also there are a dozen views and a couple forms

All this is awesome and sure useful but... I can't stop thinking in the simplest case: listing some people. Yes because every row on the output table is made upon one class instance. I can't stop thinking on how much memory and cpu is used on not used resources.

Listing 50 people means creating 50 instances, full of resources like crud, filtering processing uploads, validating rules and so on when what I need is to run a query and just output results with a simple loop.

This confuses me a lot. And not just confuse, as I already saw some apps where runtime increases exponentialy with database when business rules are a little more complex.

I think, is the case to create new classes or plain scripts to just handle the outputs and reports? If yes, so this mean double effort, making use of OOP pointless, once I would need to create many different classes for same database entity. Coding turns harder, maintenance turns no cool.

Am I missing something? Or this is a drawback of OOP approach?

Should we sacrifice a straight to the point, thin, faster code in order to get faster development and maintenance?

EDIT

As expected, some points I put before were misleading for some guys...

First, I'm seasoned to really really big projects (I worked at IBM vendoring for Sprint/Nextel USA and Directv North America, so I'm used to see some terabytes being processed daily).

When I said 50 people being retrieved from database, I don't mean strictly 50 people, I just want to gave the idea of many records. I know 50 records is nothing to today's servers. 50 million are. Imagine this last number if appropriate.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

留蓝 2024-10-15 06:47:58

这就是问题的关键。正如之前所说,每种范式都需要权衡。 OOP 有很多好处,但正如您指出的那样,它也有一些缺点。关键是称重它们。

OOP 建立的原则是开发人员昂贵而硬件便宜。它使用这一原则来实现高度可维护(从长远来看易于修复)和高度适应性的代码(从长远来看易于更改)。如果您购买 60/60 规则(其中表示60%的开发时间用于维护,60%的时间用于增强),那么可维护性就是专业编程的最终目标。

如果您了解 OOP 的工作原理(我说的是您在 OOP 范式中思考的点),一切都会变得非常容易。我认为您仍然感到困惑,因为您没有完全理解OOP。但话又说回来,它也不是编程的圣杯,所以如果您更喜欢使用另一种范例,请务必使用它。选择的存在是因为我们并不完全相同。使用你最擅长的以及最适合你想要做的最好的事情。如果你拥有的唯一工具是一把锤子,那么每个问题看起来都像钉子......

哦,与流行的观点相反,OOP 并不是要永远不要编码两次。这就是 DRY(不要重复自己)原则。虽然它经常与 OOP 一起使用,但它并不直接附加到 OOP。事实上,我建议在开发时不要遵循 DRY 作为规则。将其作为目标,但让它成为指导方针而不是规则。正如弗雷德·布鲁克斯(Fred Brooks)所说,计划扔掉一个;无论如何,你会的。(来自神话人月)。如果你严格地从不重复自己,那么当你需要扔掉第一次没有做好的事情时,你最终会重新做很多工作。只有当它构建并运行良好时,您才应该开始精简它并真正使代码干燥。 (至少个人意见)...

Here's the crux of the issue. As has been said before, there are tradeoffs to each and every paradigm. OOP has a lot of benefits, but it also has some negatives as you point out. The key is weighing them.

OOP is founded on the principal that developers are expensive and hardware is cheap. It uses this principal to lead towards highly maintainable (easy to fix in the long run) and highly adaptable code (easy to change in the long run). And if you buy the 60/60 Rule (which says that 60% of development time is in maintenance and 60% of that time is due to enhancements), then maintainability is the ultimate goal for professional programming.

If you get your head around how OOP works (I'm talking to the point of where you are thinking in a OOP paradigm) everything becomes really easy. I think you're still getting confused because you don't fully understand OOP. But then again, it's not the holy-grail of programming either, so if you're more comfortable using another paradigm, by all means use it. Choices exist because we are not all identical. Use what you're best at and what fits what you are trying to do best. If the only tool you have is a hammer, every problem looks like a nail...

Oh, and contrary to popular opinion, OOP is not about never coding anything twice. That's the DRY (Don't Repeat Yourself) principal. While it's often used with OOP, it's not directly attached to. In fact, I'd suggest while developing that you don't follow DRY as a rule. Shoot for it as a goal, but let it be a guideline more than a rule. As Fred Brooks said, plan to throw one away; you will, anyhow. (From The Mythical Man-Month ). If you strictly never repeat yourself, you're going to wind up re-doing a lot of work when it comes time to throw something away that you didn't get right the first time around. Only when it's built and running good should you start slimming it down and really making the code DRY. (personal opinion at least)...

妄想挽回 2024-10-15 06:47:58

正如你所说,这是一个范例。与任何其他范例一样,它也有优点和缺点。我认为你错误的地方在于什么是实质性重要的概念。是什么让 50 个实例成为一个大数字?也许对您来说,跟踪 50 个谨慎的事物很困难(对所有人来说可能都是如此),但这并不意味着这对计算机来说很困难。这 50 个并不大,只是因为它对你来说看起来很大。与您用于检索数据和整理结果的简单脚本示例相比,它确实很大,但是权衡应该是显而易见的,当您指出 OOP 的优点时,您列出了其中的大部分。更有趣的一点是,当这些优势大于劣势时。与您在此处确定的内容相比,该判断调用涉及的内容要多得多,包括代码库的大小、涉及的开发人员数量、他们彼此之间的相对技能、代码将在生产环境中保留多长时间等等。

It's as you said, a paradigm. It has strengths and weaknesses like any other paradigm. Where I think you're mistaken is the notion of what is materially significant. What makes 50 instances a big number? Perhaps to you keeping track of 50 discreet things is difficult (likely so for all humans), but that doesn't mean it's difficult for a computer. That 50 isn't big just because it seems big to you. It is certainly big compared to your example of a simple script to retrieve the data and collate the results, but the tradeoffs should be obvious, you listed most of them when you pointed out the strengths of OOP. The more interesting point to consider is when those strengths outweigh the weaknesses. Much more goes into that judgment call than what you've identified here, including the size of the codebase, the number of developers involved, their relative skill to each other, how long the code will remain in production, and much more.

伪装你 2024-10-15 06:47:58

为您提供一个简单的例子来说明您主要关心的问题:

$list = DB::query($query);

foreach ($list as $person)
{
  // $person->name
  // $person->address
  // .. and so on 
}

首先,如果您遇到这样的情况:每个人都有一个类的实例,当您想要它们的列表时,那么这是糟糕的编程一开始,你应该复习一下你自己的 OOP 知识(尽量不要无礼,抱歉,如果我是这样的话)。

To provide you a simple example about what seems to be your main concern :

$list = DB::query($query);

foreach ($list as $person)
{
  // $person->name
  // $person->address
  // .. and so on 
}

First of all, if you come to a point were you have an instance of a class per person, when you want a list of them, then it's bad programming from the very beginning and you should review your own knowledge of OOP (trying not to be rude, sorry if I am).

断舍离 2024-10-15 06:47:58

恐怕你缺少的是长期从事大项目的真实经验。这意味着你有100%的理论概念,但它们只是理论。当我第一次学习函数编程(C语言)时,我想知道为什么我们需要这个。但当我开始编写比以前更大的东西时,我意识到为什么我们需要它们。当我第一次学习 OOP 时也会发生同样的情况。为什么我们需要这个?但现在没有它我就无法思考太多。所以我的总结是,尝试为一些真正的大项目做出贡献。至少在软件开发中,仅有理论是不够的。

如果您已经有足够的大型项目经验,那么请忽略这个答案。

I'm afraid that what you are missing is the real experience of working long time with a big project. That means you have 100% theoretical concepts, but they are theoretical. When I first learned programming function (in C), I wondered why we need this. But then when I started coding something bigger than before I realized why we need them. Same happens when I first learned OOP. Why we need this? But now I can't think much without it. So my summery is, try to contribute in some real big project. At least in software development, only theory is not sufficient.

And if you are already experienced with enough big projects, then please ignore this answer.

影子的影子 2024-10-15 06:47:58

您将框架与范式混淆了。

框架是一种结构,您可以在其中进行编码以使某些内容更易于维护。在这种情况下,您使用的框架以对象为中心,这些对象知道如何出去并获取自己的数据。

这是一种简单化的方法,正如您所发现的,可能会导致查询数量呈指数级增长。

更好的方法是创建一个工厂类,它返回包含所有地址的人员数组。该工厂对象会合并您的请求,并在创建对象之前通过将一行从数据库(或 DTO)传递到 Person 的每个新实例来运行尽可能少的查询。

请记住,并非所有对象都与现实世界直接相似。人不是工厂制造出来的,但工厂里并没有真正的人,不是吗?

工厂+代表性对象+(可选)数据传输对象是大多数面向对象的大型应用程序中可靠且可靠的框架组件。

但并非全部。还有其他方法可以给这只猫剥皮。

OO 不是这里的问题。你的规则是。您正在使用的框架是。 (自我强加或第三者,没关系)

记住。 OOP 就是永远不要对任何东西进行两次编码。框架是有选择地决定对哪些内容进行两次编码,以使代码易于更新、升级和以其他方式维护。

Your are confusing frameworks with the paradigm.

A framework is the structure in which you code to make something easier to maintain. In this case, you are using a framework centered around objects that know how to go out and get their own data.

This is a simplistic approach, and as you've found, can lead to exponential growth in number of queries.

A better way is to create a factory class that returns arrays of Persons with all their addresses. This factory object consolidates your request and runs as few queries as possible before creating objects by passing a row from the database (or a DTO) to each new instance of a Person.

Remember, not all objects are a direct analogue to the real world. People are not made in factories, but you don't really have people there, do you?

Factory + Representative Object + (optionally) a Data Transfer Object is a ROBUST and tried-and-true framework component in most large-scale applications that are Object Oriented.

But not all. There are other ways to skin this cat.

OO isn't the problem here. Your rules are. Your framework that you are working in is. (Self-imposed or 3rd Party, it doesn't matter)

Remember. OOP is about never coding anything twice. Frameworks are about selectively deciding what to code twice in the interest of making the code easy to update, upgrade, and otherwise maintain.

相权↑美人 2024-10-15 06:47:58

如果你看看 DDD,你就会发现有一个独立的领域层,其中包含领域实体;它们每个都包含属性和域逻辑。另一层是基础设施,其中包含存储库(您的 CRUD 操作是针对特定资源和技术实施的)。

检索域实体列表是由存储库完成的,您得到的是域实体的 50 个实例,以及所需的域逻辑。您需要此信息,以确保您的客户不会滥用它。

你认为获得 50 个具有复杂领域逻辑的项目会毁掉你的系统吗?

If you look at DDD, you have an independent domain layer that contains the domain entities; each of them containing properties and domain logic. Another layer is infrastructure, which contains the repositories (where your CRUD operations are implemented towards a specific resource and technology).

Retrieving a list of domain entities is done by the repository, and what you get is 50 instances of the domain entities, together with the needed domain logic. You need this information, to be sure that your client doesn't abuse it.

Do you think that getting 50 items with complex domain logic will kill your system?

南风几经秋 2024-10-15 06:47:58

你因为“OOP =范例”模因而陷入困境。实际上对于 PHP 来说,它只是一种符号风格。当您拥有混合语言时,您应该为每个应用程序部分使用最佳方法。过程和对象之间的区别只是 API 的外观和感觉。

是的,有分组和继承,您可以使用对象结构更好地抽象和概括实用程序代码。但对于实际行为和功能,您不应该将自己限制于任何一种方法。不是每个钉子都是面向对象的,也不是每个螺丝都是过程化的。这一切都是为了美化 API。

另外,忘记微观性能差异。

You're stuck because of the "OOP = paradigm" meme. In reality and regarding PHP, it is just a notational style. When you have a hybrid language you should use the best approach for each application part. And the difference between procedures and objects is just the API look and feel.

Yes, there's grouping and inheritance, and you can abstract away and generalize utility code better with object structures. But for actual behaviour and functionality you shouldn't restrict yourself to either methodology. Not every nail is object-oriented, and not every screw is procedural. It's all about beautifying the API.

Also, forget about the microperformance differences.

南街女流氓 2024-10-15 06:47:58

创建 50 个实例不算什么...在遇到实际问题之前不要担心性能。大多数需要很长时间加载的脚本要么是因为它们执行复杂的查询,要么是因为必须获取远程资源。

至于工作量和可维护性问题——我想您很快就会发现,正确构建程序的最初努力是值得的。例如,如果您随后更改数据库中人员表的列名称,则只需更改一个类,而不需要更改应用程序中分布的多个查询。

Creating 50 instances is nothing... Don't worry about performance until you have an actual problem. Most scripts that take a long time to load is either because they do complex queries or have to fetch remote resources.

As to the effort and maintainability issue -- I think you'll quickly find out that the initial effort to properly structure your program will be worthwhile. For instance, if you then change the name of a column in the database for the persons' tables, you will only need to change one class, not several queries spread out through the application.

冷月断魂刀 2024-10-15 06:47:58

如果您正在编写一小段简单的代码,那么当您稍后想要修改它时,几乎没有什么开销:即使您必须从头开始重写它,也并不重要。随着系统的发展,您必须以更仔细的方式设计代码:记录接口,提供抽象,封装复杂性,并提供测试系统隔离部分的机制。 OO 提供了一组设计思想,让您可以将它们构建到代码中。

困难在于了解将变得更大、更复杂的简单代码(在这种情况下,您可能希望从 OO 设计开始)与永远不会改变的简单代码(在这种情况下,您可能需要从 OO 设计开始)之间的区别。想要做尽可能简单的事情,而不是付出完全面向对象的开销)。在这两者之间做出选择确实很困难,尽管我倾向于假设代码会增长,因为与超出其初始设计的设计不足的代码相比,过度设计的小段代码只是中等程度的糟糕。

If you're writing a short simple piece of code, there's very little overhead when you want to modify it later: even if you have to rewrite it from scratch, it doesn't really matter. As the system grows, you have to design code in a more careful way: document interfaces, provide abstractions, encapsulate complexity, and provide mechanisms to test isolated parts of the system. OO provides one set of design ideas to let you build these into your code.

The difficulty is knowing the difference between simple code that's going to become larger and more complex (in which case, you probably want to start with OO design), and when you've got simple code that's never going to change (in which case you want to do the simplest thing possible and not pay the overhead of going full OO). It's genuinely difficult to pick between these two, although I tend towards assuming code will grow, since the over-engineered small piece of code is only moderately bad compared to the under-engineered code that's grown beyond its initial design.

ぃ双果 2024-10-15 06:47:58

OOP 是一种通过应用各种概念来解决问题的方法。这些概念可以以严格的 OO 方式一起使用,也可以与其他范式中的其他概念混合和匹配。大多数现代编程语言不再纯粹是一种范例或另一种范例。它们通常结合其他范式和/或这些范式中的概念。例如,“延迟求值”,函数式编程中的一个概念可以与 OO 概念结合使用来创建延迟求值的对象列表。或者您可以简单地使用一个惰性列表来根据需要构造对象。

仅供参考您的共同点,其中许多在其他范例中是共享的。

OOP is an approach to a problem through the application of various concepts. These concepts can be used together in a strict OO fashion or can be mixed and matched with other concepts from other paradigms. Most modern programming languages are no longer purely 1 paradigm or another. They usually incorporate other paradigms and/or concepts from those paradigms. For example "lazy evaluation", a concept from functional programming can be used in concert with OO concepts to create a list of objects that are lazily evaluated. Or you could simply have a lazy list that constructs the objects as needed.

FYI your common points, many of them are shared in other paradigms.

淡淡離愁欲言轉身 2024-10-15 06:47:58

不要忘记测试!

拥有使用的实体对象允许您进行依赖项注入并在应用程序的每个级别独立提供测试和调试。这对于那些喜欢让代码无懈可击的开发人员来说是一个巨大的福音。

如果您使用 .Net 等具有 MVP 等结构的语言,则尤其如此,因为通过分离对象,您可以真正确定各个层,并且代码可重用性飞速增长。

Don't forget testing!

Having solid object that you work with allows you to do dependency injection and provide tests and debug at every level of the application independently. This is a huge boon to developers who like to make their code airtight.

This is especially true if you are using languages like .Net with a structure like MVP, because by separating out objects, you really nail down the layers and code reusability skyrockets.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文