As far as I can tell, in spite of the countless millions or billions spent on OOP education, languages, and tools, OOP has not improved developer productivity or software reliability, nor has it reduced development costs. Few people use OOP in any rigorous sense (few people adhere to or understand principles such as LSP); there seems to be little uniformity or consistency to the approaches that people take to modelling problem domains. All too often, the class is used simply for its syntactic sugar; it puts the functions for a record type into their own little namespace.
据我所知,尽管花费了数百万或数十亿美元用于OOP教育,语言和工具,但OOP并未提高开发人员的工作效率或软件可靠性,也没有降低开发成本。很少有人在任何严格意义上使用OOP(很少有人遵守或理解LSP等原则);人们对问题域建模所采用的方法几乎没有统一性或一致性。这个课程常常仅用于语法糖;它将记录类型的函数放入它们自己的小命名空间中。
I've written a large amount of code for a wide variety of applications. Although there have been places where true substitutable subtyping played a valuable role in the application, these have been pretty exceptional. In general, though much lip service is given to talk of "re-use" the reality is that unless a piece of code does exactly what you want it to do, there's very little cost-effective "re-use". It's extremely hard to design classes to be extensible in the right way, and so the cost of extension is normally so great that "re-use" simply isn't worthwhile.
我为各种各样的应用程序编写了大量代码。尽管真正可替代的子类型在应用程序中起到了重要作用,但这些都非常特殊。总的来说,虽然谈到“重复使用”的口号很多,但事实是,除非一段代码完全按照你的意愿行事,否则很少有成本效益的“重复使用”。设计类以正确的方式扩展是非常困难的,因此扩展的成本通常很高,以至于“重用”根本就不值得。
In many regards, this doesn't surprise me. The real world isn't "OO", and the idea implicit in OO--that we can model things with some class taxonomy--seems to me very fundamentally flawed (I can sit on a table, a tree stump, a car bonnet, someone's lap--but not one of those is-a chair). Even if we move to more abstract domains, OO modelling is often difficult, counterintuitive, and ultimately unhelpful (consider the classic examples of circles/ellipses or squares/rectangles).
在许多方面,这并不让我感到惊讶。现实世界不是“OO”,OO隐含的想法 - 我们可以用某种类别分类来模拟事物 - 在我看来非常根本性的缺陷(我可以坐在桌子上,树桩上,汽车引擎盖上)某人的膝盖 - 但不是其中之一 - 一把椅子)。即使我们转向更抽象的领域,OO建模通常也很困难,违反直觉,最终无益(考虑圆/椭圆或正方形/矩形的经典例子)。
So what am I missing here? Where's the value of OOP, and why has all the time and money failed to make software any better?
那我在这里错过了什么? OOP的价值在哪里?为什么所有的时间和金钱都无法使软件变得更好?
45 个解决方案
#1
24
There's no empirical evidence that suggests that object orientation is a more natural way for people to think about the world. There's some work in the field of psychology of programming that shows that OO is not somehow more fitting than other approaches.
没有经验证据表明,面向对象是人们思考世界的一种更自然的方式。在编程心理学领域有一些工作表明OO在某种程度上不比其他方法更合适。
Object-oriented representations do not appear to be universally more usable or less usable.
面向对象的表示似乎没有普遍的可用性或更少的可用性。
It is not enough to simply adopt OO methods and require developers to use such methods, because that might have a negative impact on developer productivity, as well as the quality of systems developed.
仅仅采用OO方法并要求开发人员使用这些方法是不够的,因为这可能会对开发人员的工作效率以及开发的系统质量产生负面影响。
Which is from "On the Usability of OO Representations" from Communications of the ACM Oct. 2000. The articles mainly compares OO against theprocess-oriented approach. There's lots of study of how people who work with the OO method "think" (Int. J. of Human-Computer Studies 2001, issue 54, or Human-Computer Interaction 1995, vol. 10 has a whole theme on OO studies), and from what I read, there's nothing to indicate some kind of naturalness to the OO approach that makes it better suited than a more traditional procedural approach.
这是来自2000年10月ACM通讯的“关于OO表示的可用性”。这些文章主要将OO与面向过程的方法进行比较。关于如何使用OO方法“思考”的人们进行了大量研究(Int.J. of Human-Computer Studies 2001,issue 54,或Human-Computer Interaction 1995,vol.10,OO研究的整个主题),从我读到的内容来看,没有任何迹象表明OO方法具有某种自然性,使其比传统的程序方法更适合。
#2
119
The real world isn't "OO", and the idea implicit in OO--that we can model things with some class taxonomy--seems to me very fundamentally flawed
现实世界不是“OO”,OO隐含的想法 - 我们可以用某种类别分类法来模拟事物 - 在我看来基本上是有缺陷的
While this is true and has been observed by other people (take Stepanov, inventor of the STL), the rest is nonsense. OOP may be flawed and it certainly is no silver bullet but it makes large-scale applications much simpler because it's a great way to reduce dependencies. Of course, this is only true for “good” OOP design. Sloppy design won't give any advantage. But good, decoupled design can be modelled very well using OOP and not well using other techniques.
虽然这是事实并且已被其他人观察到(采用STL的发明者Stepanov),其余的都是无稽之谈。 OOP可能存在缺陷,它肯定不是银弹,但它使大规模应用程序变得更加简单,因为它是减少依赖性的好方法。当然,这只适用于“好”的OOP设计。邋design的设计不会带来任何好处。但好的,解耦设计可以使用OOP很好地建模,而不是很好地使用其他技术。
There are much better, more universal models (Haskell's type model comes to mind) but these are also often more complicated and/or difficult to implement efficiently. OOP is a good trade-off between extremes.
有更好的,更通用的模型(Haskell的类型模型浮现在脑海中),但这些模型通常也更复杂和/或难以有效实施。 OOP是极端之间的良好平衡。
#3
45
OOP isn't about creating re-usable classes, its about creating Usable classes.
OOP不是关于创建可重用的类,而是关于创建可用类。
#4
42
All too often, the class is used simply for its syntactic sugar; it puts the functions for a record type into their own little namespace.
这个课程常常仅用于语法糖;它将记录类型的函数放入它们自己的小命名空间中。
Yes, I find this to be too prevalent as well. This is not Object Oriented Programming. It's Object Based Programming and data centric programing. In my 10 years of working with OO Languages, I see people mostly doing Object Based Programming. OBP breaks down very quickly IMHO since you are essentially getting the worst of both words: 1) Procedural programming without adhering to proven structured programming methodology and 2) OOP without adhering to to proven OOP methodology.
是的,我发现这也太普遍了。这不是面向对象的编程。它是基于对象的编程和以数据为中心的编程。在与OO Languages合作的10年中,我发现大多数人都在进行基于对象的编程。 OBP很快崩溃了恕我直言,因为你基本上得到了两个词中最糟糕的一个:1)程序编程没有遵循经过验证的结构化编程方法和2)OOP而不遵守经过验证的OOP方法。
OOP done right is a beautiful thing. It makes very difficult problems easy to solve, and to the uninitiated (not trying to sound pompous there), it can almost seem like magic. That being said, OOP is just one tool in the toolbox of programming methodologies. It is not the be all end all methodology. It just happens to suit large business applications well.
完成OOP是一件美好的事情。这使得非常难以解决的问题变得非常困难,对于那些没有经验的人(不要试图在那里听起来很夸张),它几乎看起来像是魔术。话虽这么说,OOP只是编程方法工具箱中的一个工具。它不是所有方法的全部。它恰好适合大型商业应用程序。
Most developers who work in OOP languages are utilizing examples of OOP done right in the frameworks and types that they use day-to-day, but they just aren't aware of it. Here are some very simple examples: ADO.NET, Hibernate/NHibernate, Logging Frameworks, various language collection types, the ASP.NET stack, The JSP stack etc... These are all things that heavily rely on OOP in their codebases.
大多数使用OOP语言的开发人员都在使用他们日常使用的框架和类型中完成的OOP示例,但他们并没有意识到这一点。下面是一些非常简单的示例:ADO.NET,Hibernate / NHibernate,Logging Frameworks,各种语言集合类型,ASP.NET堆栈,JSP堆栈等......这些都是在代码库中严重依赖OOP的所有东西。
#5
32
Reuse shouldn't be a goal of OOP - or any other paradigm for that matter.
重用不应该是OOP的目标 - 或者任何其他范例。
Reuse is a side-effect of an good design and proper level of abstraction. Code achieves reuse by doing something useful, but not doing so much as to make it inflexible. It does not matter whether the code is OO or not - we reuse what works and is not trivial to do ourselves. That's pragmatism.
重用是良好设计和适当抽象级别的副作用。代码通过做一些有用的事情来实现重用,但却没有做到让它变得不灵活。代码是否为OO并不重要 - 我们重用可行的方法,而不是自己做的微不足道。这是实用主义。
The thought of OO as a new way to get to reuse through inheritance is fundamentally flawed. As you note the LSP violations abound. Instead, OO is properly thought of as a method of managing the complexity of a problem domain. The goal is maintainability of a system over time. The primary tool for achieving this is the separation of public interface from a private implementation. This allows us to have rules like "This should only be modified using ..." enforced by the compiler, rather than code review.
OO作为一种通过继承重用的新方法的思想从根本上是有缺陷的。正如您所注意到的那样,LSP违规很多。相反,OO被恰当地认为是管理问题域复杂性的一种方法。目标是随着时间的推移系统的可维护性。实现这一目标的主要工具是将公共接口与私有实现分离。这允许我们使用编译器强制执行的规则,例如“只应使用...修改”,而不是代码审查。
Using this, I'm sure you will agree, allows us to create and maintain hugely complex systems. There is lots of value in that, and it is not easy to do in other paradigms.
使用它,我相信你会同意,允许我们创建和维护非常复杂的系统。这有很多价值,在其他范例中并不容易。
#6
28
Verging on religious but I would say that you're painting an overly grim picture of the state of modern OOP. I would argue that it actually has reduced costs, made large software projects manageable, and so forth. That doesn't mean it's solved the fundamental problem of software messiness, and it doesn't mean the average developer is an OOP expert. But the modularization of function into object-components has certainly reduced the amount of spaghetti code out there in the world.
关注宗教,但我会说你正在描绘现代OOP状态的过于严峻的画面。我认为它实际上降低了成本,使大型软件项目易于管理,等等。这并不意味着它解决了软件混乱的根本问题,并不意味着普通开发人员是OOP专家。但是,将功能模块化为对象组件确实减少了世界上意大利面条代码的数量。
I can think of dozens of libraries off the top of my head which are beautifully reusable and which have saved time and money that can never be calculated.
我可以想到几十个我头顶的图书馆,它们可以重复使用,节省了时间和金钱,无法计算。
But to the extent that OOP has been a waste of time, I'd say it's because of lack of programmer training, compounded by the steep learning curve of learning a language specific OOP mapping. Some people "get" OOP and others never will.
但是,就OOP浪费时间而言,我认为这是因为缺乏程序员培训,而且学习语言特定OOP映射的学习曲线陡峭。有些人“得到”OOP而其他人永远不会。
#7
21
I think the use of opaque context objects (HANDLEs in Win32, FILE*s in C, to name two well-known examples--hell, HANDLEs live on the other side of the kernel-mode barrier, and it really doesn't get much more encapsulated than that) is found in procedural code too; I'm struggling to see how this is something particular to OOP.
我认为使用不透明的上下文对象(在Win32中的HANDLEs,在C中的FILE *,用来命名两个着名的例子 - 地狱,HANDLEs生活在内核模式障碍的另一边,它真的没有得到在程序代码中也可以找到比封装更多的封装;我很难看到这对OOP来说是特别的。
HANDLE
s (and the rest of the WinAPI) is OOP! C doesn't support OOP very well so there's no special syntax but that doesn't mean it doesn't use the same concepts. WinAPI is in every sense of the word an object-oriented framework.
HANDLEs(以及WinAPI的其余部分)是OOP! C不能很好地支持OOP,因此没有特殊的语法,但这并不意味着它不使用相同的概念。从各个方面来说,WinAPI都是面向对象的框架。
See, this is the trouble with every single discussion involving OOP or alternative techniques: nobody is clear about the definition, everyone is talking about something else and thus no consensus can be reached. Seems like a waste of time to me.
看,这是涉及OOP或替代技术的每一次讨论的问题:没有人清楚定义,每个人都在谈论其他事情,因此无法达成共识。对我来说似乎浪费时间。
#8
14
Its a programming paradigm.. Designed to make it easier for us mere mortals to break down a problem into smaller, workable pieces..
它是一种编程范例。旨在让我们的凡人更容易将问题分解成更小,更实用的部分..
If you dont find it useful.. Don't use it, don't pay for training and be happy.
如果你没有发现它有用..不要使用它,不要支付培训费用并且要开心。
I on the other hand do find it useful, so I will :)
另一方面,我发现它很有用,所以我会:)
#9
14
Relative to straight procedural programming, the first fundamental tenet of OOP is the notion of information hiding and encapsulation. This idea leads to the notion of the class that seperates the interface from implementation. These are hugely important concepts and the basis for putting a framework in place to think about program design in a different way and better (I think) way. You can't really argue against those properties - there is no trade-off made and it is always a cleaner way to modulize things.
相对于直接的程序编程,OOP的第一个基本原则是信息隐藏和封装的概念。这个想法导致类的概念将接口与实现分开。这些是非常重要的概念,也是建立框架的基础,以不同的方式和更好的(我认为)方式思考程序设计。你不能真正反对这些属性 - 没有做出权衡,它总是一种更简洁的方式来模块化。
Other aspects of OOP including inheritance and polymorphism are important too, but as others have alluded to, those are commonly over used. ie: Sometimes people use inheritance and/or polymorphism because they can, not because they should have. They are powerful concepts and very useful, but need to be used wisely and are not automatic winning advantages of OOP.
OOP的其他方面包括继承和多态也很重要,但正如其他人所提到的那样,这些方面通常被过度使用。即:有时人们使用继承和/或多态,因为它们可以,而不是因为它们应该具有。它们是强大的概念,非常有用,但需要明智地使用,而不是OOP的自动获胜优势。
Relative to re-use. I agree re-use is over sold for OOP. It is a possible side effect of well defined objects, typically of more primitive/generic classes and is a direct result of the encapsulation and information hiding concepts. It is potentially easier to be re-used because the interfaces of well defined classes are just simply clearer and somewhat self documenting.
相对于重复使用。我同意重复使用已超过OOP。这是明确定义的对象的可能的副作用,通常是更原始/通用的类,并且是封装和信息隐藏概念的直接结果。重新使用它可能更容易,因为定义良好的类的接口只是更简单,有点自我记录。
#10
12
The problem with OOP is that it was oversold.
OOP的问题在于它是超卖的。
As Alan Kay originally conceived it, it was a great alternative to the prior practice of having raw data and all-global routines.
正如Alan Kay最初设想的那样,它是原始数据和全球惯例的先前实践的一个很好的替代品。
Then some management-consultant types latched onto it and sold it as the messiah of software, and lemming-like, academia and industry tumbled along after it.
然后一些管理顾问类型锁定它并将其作为软件的救世主出售,并且类似于旅鼠,学术界和工业界随之而来。
Now they are lemming-like tumbling after other good ideas being oversold, such as functional programming.
现在,在其他好的想法被超卖之后,它们就像在功能性编程中一样翻滚。
So what would I do differently? Plenty, and I wrote a book on this. (It's out of print - I don't get a cent, but you can still get copies.)Amazon
那么我会做些什么呢?很多,我写了一本关于此的书。 (已经绝版 - 我没有得到一分钱,但你仍然可以获得副本。)亚马逊
My constructive answer is to look at programming not as a way of modeling things in the real world, but as a way of encoding requirements.
我的建设性答案是将编程看作是在现实世界中对事物进行建模的一种方式,而是作为编码需求的一种方式。
That is very different, and is based on information theory (at a level that anyone can understand). It says that programming can be looked at as a process of defining languages, and skill in doing so is essential for good programming.
这是非常不同的,并且基于信息理论(在任何人都能理解的水平上)。它说编程可以看作是定义语言的过程,这样做的技巧对于良好的编程至关重要。
It elevates the concept of domain-specific-languages (DSLs). It agrees emphatically with DRY (don't repeat yourself). It gives a big thumbs-up to code generation. It results in software with massively less data structure than is typical for modern applications.
它提升了领域特定语言(DSL)的概念。它强烈同意DRY(不要重复自己)。它给代码生成带来了很大的好感。它导致软件的数据结构比现代应用程序的典型数据少。
It seeks to re-invigorate the idea that the way forward lies in inventiveness, and that even well-accepted ideas should be questioned.
它旨在重新激发前进的道路在于创造性的想法,并且应该质疑即使是被广泛接受的想法。
#11
11
HANDLEs (and the rest of the WinAPI) is OOP!
HANDLEs(以及WinAPI的其余部分)是OOP!
Are they, though? They're not inheritable, they're certainly not substitutable, they lack well-defined classes... I think they fall a long way short of "OOP".
他们是吗?它们不是可继承的,它们肯定不是可替代的,它们缺乏明确定义的类......我认为它们远远没有“OOP”。
Have you ever created a window using WinAPI? Then you should know that you define a class (RegisterClass
), create an instance of it (CreateWindow
), call virtual methods (WndProc
) and base-class methods (DefWindowProc
) and so on. WinAPI even takes the nomenclature from SmallTalk OOP, calling the methods “messages” (Window Messages).
你有没有用WinAPI创建一个窗口?然后你应该知道你定义了一个类(RegisterClass),创建它的一个实例(CreateWindow),调用虚方法(WndProc)和基类方法(DefWindowProc)等等。 WinAPI甚至采用SmallTalk OOP的命名法,调用方法“消息”(Window Messages)。
Handles may not be inheritable but then, there's final
in Java. They don't lack a class, they are a placeholder for the class: That's what the word “handle” means. Looking at architectures like MFC or .NET WinForms it's immediately obvious that except for the syntax, nothing much is different from the WinAPI.
句柄可能不是可继承的,但是,Java中有最终版本。他们不缺课,他们是班级的占位符:这就是“句柄”这个词的含义。看看像MFC或.NET WinForms这样的架构,很明显,除了语法之外,与WinAPI没什么不同。
#12
11
Yes OOP did not solve all our problems, sorry about that. We are, however working on SOA which will solve all those problems.
是的,OOP没有解决我们所有的问题,对不起。然而,我们正致力于解决所有这些问题的SOA。
#13
10
OOP lends itself well to programming internal computer structures like GUI "widgets", where for example SelectList and TextBox may be subtypes of Item, which has common methods such as "move" and "resize".
OOP非常适合编程内部计算机结构,如GUI“小部件”,例如SelectList和TextBox可能是Item的子类型,它具有常见的方法,如“move”和“resize”。
The trouble is, 90% of us work in the world of business where we are working with business concepts such as Invoice, Employee, Job, Order. These do not lend themselves so well to OOP because the "objects" are more nebulous, subject to change according to business re-engineering and so on.
麻烦的是,我们90%的人在业务领域工作,我们正在处理发票,员工,工作,订单等业务概念。这些不适合OOP,因为“对象”更加模糊,可根据业务重新设计等进行更改。
The worst case is where OO is enthusiastically applied to databases, including the egregious OO "enhancements" to SQL databases - which are rightly ignored except by database noobs who assume they must be the right way to do things because they are newer.
最糟糕的情况是OO热情地应用于数据库,包括对SQL数据库的恶劣OO“增强” - 除了数据库noobs之外被正确忽略,他们认为他们必须是正确的做事方式,因为它们更新。
#14
10
In my experience of reviewing code and design of projects I have been through, the value of OOP is not fully realised because alot of developers have not properly conceptualised the object-oriented model in their minds. Thus they do not program with OO design, very often continuing to write top-down procedural code making the classes a pretty flat design. (if you can even call that "design" in the first place)
根据我审查代码和项目设计的经验,OOP的价值还没有完全实现,因为很多开发人员没有在他们的脑海中正确地概念化面向对象的模型。因此,他们不使用OO设计编程,经常继续编写自上而下的程序代码,使这些类成为一个非常扁平的设计。 (如果你甚至可以称之为“设计”)
It is pretty scary to observe how little colleagues know about what an abstract class or interface are, let alone properly design an inheritance hierarchy to suit the business needs.
观察同事们对抽象类或接口的了解程度是多么可怕,更不用说正确设计继承层次结构以满足业务需求。
However, when good OO design is present, it is just sheer joy reading the code and seeing the code naturally fall into place into intuitive components/classes. I have always perceived system architecture and design like designing the various departments and staff jobs in a company - all are there to accomplish a certain piece of work in the grand scheme of things, emitting the synergy required to propel the organisation/system forward.
然而,当存在良好的OO设计时,阅读代码并且看到代码自然地落入直观的组件/类中只是纯粹的快乐。我一直认为系统架构和设计就像设计公司中的各个部门和员工工作一样 - 所有这些都是为了完成宏观方案中的某项工作,从而发挥推动组织/系统前进所需的协同作用。
That, of course, is quite rare unfortunately. Like the ratio of beautifully-designed versus horrendously-designed physical objects in the world, the same can pretty much be said about software engineering and design. Having the good tools at one's disposal does not necessarily confer good practices and results.
当然,这很不幸。就像世界上设计精美的设计与可怕设计的物理对象的比例一样,软件工程和设计也是如此。拥有良好的工具并不一定能带来良好的实践和结果。
#15
9
Maybe a bonnet, lap or a tree is not a chair but they all are ISittable.
也许发动机罩,膝盖或树不是椅子,但它们都是ISittable。
#16
8
I think those real world things are objects
我认为那些现实世界的东西都是物体
You do?
What methods does an invoice have? Oh, wait. It can't pay itself, it can't send itself, it can't compare itself with the items that the vendor actually delivered. It doesn't have any methods at all; it's totally inert and non-functional. It's a record type (a struct, if you prefer), not an object.
发票有哪些方法?等一下。它不能自己付费,它不能自己发送,它无法与供应商实际交付的项目进行比较。它根本没有任何方法;它是完全惰性和无功能的。它是一种记录类型(结构,如果你愿意),而不是一个对象。
Likewise the other things you mention.
同样你提到的其他事情。
Just because something is real does not make it an object in the OO sense of the word. OO objects are a peculiar coupling of state and behaviour that can act of their own accord. That isn't something that's abundant in the real world.
仅仅因为某些东西是真实的并不能使它成为OO意义上的一个对象。 OO对象是状态和行为的特殊耦合,可以自行行动。这不是现实世界中丰富的东西。
#17
7
I have been writing OO code for the last 9 years or so. Other than using messaging, it's hard for me to imagine other approach. The main benefit I see totally in line with what CodingTheWheel said: modularisation. OO naturally leads me to construct my applications from modular components that have clean interfaces and clear responsibilities (i.e. loosely coupled, highly cohesive code with a clear separation of concerns).
我在过去9年左右一直在编写OO代码。除了使用消息传递之外,我很难想象其他方法。我看到的主要好处完全符合CodingTheWheel所说的:模块化。 OO自然地引导我从模块化组件构建我的应用程序,这些组件具有干净的界面和明确的职责(即松散耦合,高度内聚的代码以及明确的关注点分离)。
I think where OO breaks down is when people create deeply nested class heirarchies. This can lead to complexity. However, factoring out common finctionality into a base class, then reusing that in other descendant classes is a deeply elegant thing, IMHO!
我认为OO崩溃的地方是人们创建深层嵌套的类heirarchies。这可能导致复杂性。然而,将共同的功能分解为基类,然后在其他后代类中重用它是一个非常优雅的事情,恕我直言!
#18
7
In the first place, the observations are somewhat sloppy. I don't have any figures on software productivity, and have no good reason to believe it's not going up. Further, since there are many people who abuse OO, good use of OO would not necessarily cause a productivity improvement even if OO was the greatest thing since peanut butter. After all, an incompetent brain surgeon is likely to be worse than none at all, but a competent one can be invaluable.
首先,观察结果有点草率。我没有关于软件生产力的数据,也没有充分的理由相信它没有上升。此外,由于有许多人滥用OO,即使OO是花生酱以来最好的东西,使用OO也不一定能提高生产率。毕竟,一个不称职的脑外科医生可能会比没有人更糟糕,但一个称职的脑外科医生可能是非常宝贵的。
That being said, OO is a different way of arranging things, attaching procedural code to data rather than having procedural code operate on data. This should be at least a small win by itself, since there are cases where the OO approach is more natural. There's nothing stopping anybody from writing a procedural API in C++, after all, and so the option of providing objects instead makes the language more versatile.
话虽这么说,面向对象是一种不同的排列方式,将过程代码附加到数据上,而不是让程序代码对数据进行操作。这应该至少是一个小胜利,因为有些情况下OO方法更自然。毕竟,没有什么可以阻止任何人在C ++中编写程序API,因此提供对象的选项使语言更加通用。
Further, there's something OO does very well: it allows old code to call new code automatically, with no changes. If I have code that manages things procedurally, and I add a new sort of thing that's similar but not identical to an earlier one, I have to change the procedural code. In an OO system, I inherit the functionality, change what I like, and the new code is automatically used due to polymorphism. This increases the locality of changes, and that is a Good Thing.
此外,OO做得非常好:它允许旧代码自动调用新代码,无需更改。如果我有程序性地管理事物的代码,并且我添加了一个与之前的类似但不相同的新类型的东西,我必须更改过程代码。在OO系统中,我继承了功能,改变了我喜欢的内容,并且由于多态性而自动使用新代码。这增加了变化的位置,这是一件好事。
The downside is that good OO isn't free: it requires time and effort to learn it properly. Since it's a major buzzword, there's lots of people and products who do it badly, just for the sake of doing it. It's not easier to design a good class interface than a good procedural API, and there's all sorts of easy-to-make errors (like deep class hierarchies).
缺点是良好的OO不是免费的:需要时间和精力来正确学习它。由于它是一个重要的流行词,因此有很多人和产品做得很差,只是为了做到这一点。设计一个好的类接口而不是一个好的过程API并不容易,而且还有各种容易出错的错误(比如深层次的层次结构)。
Think of it as a different sort of tool, not necessarily generally better. A hammer in addition to a screwdriver, say. Perhaps we will eventually get out of the practice of software engineering as knowing which wrench to use to hammer the screw in.
将其视为一种不同的工具,通常不一定更好。比如锤子和螺丝刀。也许我们最终会从软件工程的实践中走出来,因为他知道用什么扳手敲击螺钉。
#19
6
@Sean
However, factoring out common finctionality into a base class, then reusing that in other descendant classes is a deeply elegant thing, IMHO!
然而,将共同的功能分解为基类,然后在其他后代类中重用它是一个非常优雅的事情,恕我直言!
But "procedural" developers have been doing that for decades anyway. The syntax and terminology might differ, but the effect is identical. There is more to OOP than "reusing common functionality in a base class", and I might even go so far as to say that that is hard to describe as OOP at all; calling the same function from different bits of code is a technique as old as the subprocedure itself.
但无论如何,“程序化”开发人员已经这样做了几十年。语法和术语可能不同,但效果相同。 OOP比“重用基类中的常用功能”还要多,我甚至可能会说很难将其描述为OOP;从不同的代码位调用相同的函数是一种与子过程本身一样古老的技术。
#20
6
@Konrad
OOP may be flawed and it certainly is no silver bullet but it makes large-scale applications much simpler because it's a great way to reduce dependencies
OOP可能存在缺陷,它肯定不是银弹,但它使大规模应用程序变得更加简单,因为它是减少依赖性的好方法
That is the dogma. I am not seeing what makes OOP significantly better in this regard than procedural programming of old. Whenever I make a procedure call I am isolating myself from the specifics of the implementation.
这就是教条。在这方面,我没有看到OOP比旧程序编程更好的原因。每当我进行程序调用时,我都会将自己从实现的细节中分离出来。
#21
6
To me, there is a lot of value in the OOP syntax itself. Using objects that attempt to represent real things or data structures is often much more useful than trying to use a bunch of different flat (or "floating") functions to do the same thing with the same data. There is a certain natural "flow" to things with good OOP that just makes more sense to read, write, and maintain long term.
对我来说,OOP语法本身有很多价值。使用试图表示真实事物或数据结构的对象通常比尝试使用一堆不同的平面(或“浮动”)函数用相同的数据做同样的事情更有用。对具有良好OOP的事物有一定的自然“流动”,这对于长期阅读,编写和维护更有意义。
It doesn't necessarily matter that an Invoice isn't really an "object" with functions that it can perform itself - the object instance can exist just to perform functions on the data without having to know what type of data is actually there. The function "invoice.toJson()" can be called successfully without having to know what kind of data "invoice" is - the result will be Json, no matter it if comes from a database, XML, CSV, or even another JSON object. With procedural functions, you all the sudden have to know more about your data, and end up with functions like "xmlToJson()", "csvToJson()", "dbToJson()", etc. It eventually becomes a complete mess and a HUGE headache if you ever change the underlying data type.
Invoice实际上并不一定是具有可以自己执行的函数的“对象” - 对象实例只是为了对数据执行函数而不必知道实际存在哪种类型的数据。可以成功调用函数“invoice.toJson()”,而无需知道“发票”是什么类型的数据 - 结果将是Json,无论它来自数据库,XML,CSV,还是其他JSON对象。使用过程函数,您突然必须了解有关数据的更多信息,并最终使用“xmlToJson()”,“csvToJson()”,“dbToJson()”等函数。它最终变得完全混乱,并且如果您更改基础数据类型,那将会非常头痛。
The point of OOP is to hide the actual implementation by abstracting it away. To achieve that goal, you must create a public interface. To make your job easier while creating that public interface and keep things DRY, you must use concepts like abstract classes, inheritance, polymorphism, and design patterns.
OOP的要点是通过抽象来隐藏实际的实现。要实现该目标,您必须创建一个公共接口。为了使您的工作更容易创建公共接口并保持干燥,您必须使用抽象类,继承,多态和设计模式等概念。
So to me, the real overriding goal of OOP is to make future code maintenance and changes easier. But even beyond that, it can really simplify things a lot when done correctly in ways that procedural code never could. It doesn't matter if it doesn't match the "real world" - programming with code is not interacting with real world objects anyways. OOP is just a tool that makes my job easier and faster - I'll go for that any day.
所以对我来说,OOP真正的首要目标是使未来的代码维护和更改更容易。但即使超越这一点,当以程序代码永远无法完成的方式正确完成时,它可以真正简化很多事情。如果它与“现实世界”不匹配并不重要 - 无论如何,用代码编程都不会与现实世界的对象进行交互。 OOP只是一种工具,使我的工作更轻松,更快 - 我会在任何一天都去做。
#22
5
@CodingTheWheel
But to the extent that OOP has been a waste of time, I'd say it's because of lack of programmer training, compounded by the steep learning curve of learning a language specific OOP mapping. Some people "get" OOP and others never will.
但是,就OOP浪费时间而言,我认为这是因为缺乏程序员培训,而且学习语言特定OOP映射的学习曲线陡峭。有些人“得到”OOP而其他人永远不会。
I dunno if that's really surprising, though. I think that technically sound approaches (LSP being the obvious thing) make hard to use, but if we don't use such approaches it makes the code brittle and inextensible anyway (because we can no longer reason about it). And I think the counterintuitive results that OOP leads us to makes it unsurprising that people don't pick it up.
不过,如果这真的令人惊讶,我不知道。我认为技术上合理的方法(LSP显而易见)难以使用,但如果我们不使用这种方法,它会使代码变得脆弱且无法表达(因为我们不能再对它进行推理)。而且我认为OOP导致我们采取违反直觉的结果会让人们不会惊讶于人们不会接受它。
More significantly, since software is already fundamentally too hard for normal humans to write reliably and accurately, should we really be extolling a technique that is consistently taught poorly and appears hard to learn? If the benefits were clear-cut then it might be worth persevering in spite of the difficulty, but that doesn't seem to be the case.
更重要的是,由于软件对于普通人来说已经基本上难以可靠和准确地编写,我们是否真的应该赞美一种一贯教导并且难以学习的技术?如果利益是明确的,那么尽管有困难,它仍然值得坚持,但似乎并非如此。
#23
5
@Jeff
Relative to straight procedural programming, the first fundamental tenet of OOP is the notion of information hiding and encapsulation. This idea leads to the notion of the class that seperates the interface from implementation.
相对于直接的程序编程,OOP的第一个基本原则是信息隐藏和封装的概念。这个想法导致类的概念将接口与实现分开。
Which has the more hidden implementation: C++'s iostreams, or C's FILE*s?
哪个有更隐蔽的实现:C ++的iostreams,或C的FILE * s?
I think the use of opaque context objects (HANDLEs in Win32, FILE*s in C, to name two well-known examples--hell, HANDLEs live on the other side of the kernel-mode barrier, and it really doesn't get much more encapsulated than that) is found in procedural code too; I'm struggling to see how this is something particular to OOP.
我认为使用不透明的上下文对象(在Win32中的HANDLEs,在C中的FILE *,用来命名两个着名的例子 - 地狱,HANDLEs生活在内核模式障碍的另一边,它真的没有得到在程序代码中也可以找到比封装更多的封装;我很难看到这对OOP来说是特别的。
I suppose that may be a part of why I'm struggling to see the benefits: the parts that are obviously good are not specific to OOP, whereas the parts that are specific to OOP are not obviously good! (this is not to say that they are necessarily bad, but rather that I have not seen the evidence that they are widely-applicable and consistently beneficial).
我想这可能是我为什么要努力看到好处的一部分:明显好的部分并不是OOP特有的,而OOP特有的部分显然不是很好! (这并不是说它们一定是坏的,而是我没有看到它们广泛适用且始终有益的证据)。
#24
5
In the only dev blog I read, by that Joel-On-Software-Founder-of-SO guy, I read a long time ago that OO does not lead to productivity increases. Automatic memory management does. Cool. Who can deny the data?
在我读过的唯一的开发博客中,我是那个Joel-On-Software-W创始人,我读过很久以前OO并没有提高生产力。自动内存管理。凉。谁可以否认这些数据?
I still believe that OO is to non-OO what programming with functions is to programming everything inline.
(And I should know, as I started with GWBasic.) When you refactor code to use functions,variable2654
becomes
variable3
of the method you're in. Or, better yet, it's got a name that you can understand,
and if the function is short, it's called
value
and that's sufficient for full comprehension.
When code with no functions becomes code with methods, you get to delete miles of code.
当没有函数的代码成为带方法的代码时,您可以删除数英里的代码。
When you refactor code to be truly OO, b
, c
, q
, and Z
become this
, this
, this
and this
. And since I don't believe in using the this
keyword, you get to delete miles of code. Actually, you get to do that even if you use this
.
当您将代码重构为真正的OO时,b,c,q和Z成为这个,这个,这个和这个。由于我不相信使用this关键字,因此您可以删除数英里的代码。实际上,即使你使用它,你也可以做到这一点。
I do not think OO is natural metaphor.
I don't think language is a natural metaphor either, nor do I think that Fowler's "smells" are better than saying "this code tastes bad." That said, I think that OO is not about natural metaphors and people who think the objects just pop out at you are basically missing the point. You define the object universe, and better object universes result in code that is shorter, easier to understand, works better, or all of these (and some criteria I am forgetting). I think that people who use the customers/domain's natural objects as programming objects are missing the power to redefine the universe.For instance, when you do an airline reservation system, what you call a reservation might not correspond to a legal/business reservation at all.
例如,当您进行航班预订系统时,您所谓的预订可能根本不符合法律/商业预订。
Some of the basic concepts are really cool tools
I think that most people exaggerate with that whole "when you have a hammer, they're all nails" thing. I think that the other side of the coin/mirror is just as true: when you have a gadget like polymorphism/inheritance, you begin to find uses where it fits like a glove/sock/contact-lens. The tools of OO are very powerful. Single-inheritance is, I think, absolutely necessary for people not to get carried away, my own multi-inheritance software not withstanding.What's the point of OOP?
I think it's a great way to handle an absolutely massive code base. I think it lets you organize and reorganize you code and gives you a language to do that in (beyond the programming language you're working in), and modularizes code in a pretty natural and easy-to-understand way.OOP is destined to be misunderstood by the majority of developers
This is because it's an eye-opening process like life: you understand OO more and more with experience, and start avoiding certain patterns and employing others as you get wiser. One of the best examples is that you stop using inheritance for classes that you do not control, and prefer the Facade pattern instead.Regarding your mini-essay/question
I did want to mention that you're right. Reusability is a pipe-dream, for the most part. Here's a quote from Anders Hejilsberg about that topic (brilliant) from here:
我确实想提一下你是对的。在大多数情况下,可重用性是一个梦想。以下是Anders Hejilsberg关于该主题(精彩)的引用:
If you ask beginning programmers to write a calendar control, they often think to themselves, "Oh, I'm going to write the world's best calendar control! It's going to be polymorphic with respect to the kind of calendar. It will have displayers, and mungers, and this, that, and the other." They need to ship a calendar application in two months. They put all this infrastructure into place in the control, and then spend two days writing a crappy calendar application on top of it. They'll think, "In the next version of the application, I'm going to do so much more."
如果你要求初级程序员编写一个日历控件,他们常常会自己想:“哦,我将编写世界上最好的日历控件!它将是日历类型的多态。它将有显示器,和mungers,以及这个,那个和另一个。“他们需要在两个月内发送日历应用程序。他们将所有这些基础设施放在控件中,然后花两天时间在其上面编写一个糟糕的日历应用程序。他们会想,“在下一个版本的应用程序中,我会做更多的事情。”
Once they start thinking about how they're actually going to implement all of these other concretizations of their abstract design, however, it turns out that their design is completely wrong. And now they've painted themself into a corner, and they have to throw the whole thing out. I have seen that over and over. I'm a strong believer in being minimalistic. Unless you actually are going to solve the general problem, don't try and put in place a framework for solving a specific one, because you don't know what that framework should look like.
一旦他们开始思考他们实际上将如何实现他们的抽象设计的所有其他具体化,然而事实证明他们的设计是完全错误的。而现在他们把自己画成了一个角落,他们不得不抛弃整个事物。我一遍又一遍地看到了。我坚信极简主义。除非你真的要解决一般问题,否则不要试图建立一个解决特定问题的框架,因为你不知道那个框架应该是什么样子。
#25
4
Have you ever created a window using WinAPI?
你有没有用WinAPI创建一个窗口?
More times than I care to remember.
比我记得的次数多。
Then you should know that you define a class (RegisterClass), create an instance of it (CreateWindow), call virtual methods (WndProc) and base-class methods (DefWindowProc) and so on. WinAPI even takes the nomenclature from SmallTalk OOP, calling the methods “messages” (Window Messages).
然后你应该知道你定义了一个类(RegisterClass),创建它的一个实例(CreateWindow),调用虚方法(WndProc)和基类方法(DefWindowProc)等等。 WinAPI甚至采用SmallTalk OOP的命名法,调用方法“消息”(Window Messages)。
Then you'll also know that it does no message dispatch of its own, which is a big gaping void. It also has crappy subclassing.
然后你也会知道它没有自己的消息发送,这是一个很大的空洞。它也有蹩脚的子类。
Handles may not be inheritable but then, there's final in Java. They don't lack a class, they are a placeholder for the class: That's what the word “handle” means. Looking at architectures like MFC or .NET WinForms it's immediately obvious that except for the syntax, nothing much is different from the WinAPI.
句柄可能不是可继承的,但是,Java中有最终版本。他们不缺课,他们是班级的占位符:这就是“句柄”这个词的含义。看看像MFC或.NET WinForms这样的架构,很明显,除了语法之外,与WinAPI没什么不同。
They're not inheritable either in interface or implementation, minimally substitutable, and they're not substantially different from what procedural coders have been doing since forever.
它们在接口或实现中都是不可继承的,最小的可替代性,并且它们与程序编码器一直在做的事情没有太大的不同。
Is this really it? The best bits of OOP are just... traditional procedural code? That's the big deal?
这真的吗? OOP的最佳位置只是......传统的程序代码?那是大问题?
#26
4
I agree completely with InSciTek Jeff's answer, I'll just add the following refinements:
我完全赞同InSciTek Jeff的回答,我只想添加以下改进:
- Information hiding and encapsulation: Critical for any maintainable code. Can be done by being careful in any programming language, doesn't require OO features, but doing it will make your code slightly OO-like.
- Inheritance: There is one important application domain for which all those OO is-a-kind-of and contains-a relationships are a perfect fit: Graphical User Interfaces. If you try to build GUIs without OO language support, you will end up building OO-like features anyway, and it's harder and more error-prone without language support. Glade (recently) and X11 Xt (historically) for example.
信息隐藏和封装:对于任何可维护代码都至关重要。可以通过在任何编程语言中小心,不需要OO功能来完成,但这样做会使您的代码略微类似于OO。
继承:有一个重要的应用程序域,所有这些OO是一种类型和包含 - 关系是完美契合:图形用户界面。如果您尝试在没有OO语言支持的情况下构建GUI,那么无论如何您最终都会构建类似OO的功能,并且如果没有语言支持,它将更难以且更容易出错。例如,Glade(最近)和X11 Xt(历史上)。
Using OO features (especially deeply nested abstract hierarchies), when there is no point, is pointless. But for some application domains, there really is a point.
使用OO功能(特别是深层嵌套的抽象层次结构),当没有意义时,是没有意义的。但对于某些应用领域,确实有一点意义。
#27
4
I believe the most beneficial quality of OOP is data hiding/managing. However, there are a LOT of examples where OOP is misused and I think this is where the confusion comes in.
我相信最有利的OOP质量是数据隐藏/管理。然而,有很多例子中OOP被滥用,我认为这是混乱的地方。
Just because you can make something into an object does not mean you should. However, if doing so will make your code more organized/easier to read then you definitely should.
仅仅因为你可以把东西变成对象并不意味着你应该。但是,如果这样做会使您的代码更有条理/更容易阅读,那么您绝对应该这样做。
A great practical example where OOP is very helpful is with a "product" class and objects that I use on our website. Since every page is a product, and every product has references to other products, it can get very confusing as to which product the data you have refers to. Is this "strURL" variable the link to the current page, or to the home page, or to the statistics page? Sure you could make all kinds of different variable that refer to the same information, but proCurrentPage->strURL, is much easier to understand (for a developer).
OOP非常有用的一个很好的实际例子是我在我们网站上使用的“产品”类和对象。由于每个页面都是一个产品,并且每个产品都引用了其他产品,因此您所引用的数据所引用的产品会非常混乱。这个“strURL”变量是指向当前页面,主页或统计页面的链接吗?当然,您可以制作引用相同信息的各种不同变量,但proCurrentPage-> strURL更容易理解(对于开发人员而言)。
In addition, attaching functions to those pages is much cleaner. I can do proCurrentPage->CleanCache(); Followed by proDisplayItem->RenderPromo(); If I just called those functions and had it assume the current data was available, who knows what kind of evil would occur. Also, if I had to pass the correct variables into those functions, I am back to the problem of having all kinds of variables for the different products laying around.
此外,将功能附加到这些页面更加清晰。我可以做proCurrentPage-> CleanCache();其次是proDisplayItem-> RenderPromo();如果我只是调用这些函数并让它假设当前数据可用,那么谁知道会发生什么样的邪恶。此外,如果我必须将正确的变量传递给这些函数,我回到了为不同产品提供各种变量的问题。
Instead, using objects, all my product data and functions are nice and clean and easy to understand.
相反,使用对象,我的所有产品数据和功能都很好,干净,易于理解。
However. The big problem with OOP is when somebody believes that EVERYTHING should be OOP. This creates a lot of problems. I have 88 tables in my database. I only have about 6 classes, and maybe I should have about 10. I definitely don't need 88 classes. Most of the time directly accessing those tables is perfectly understandable in the circumstances I use it, and OOP would actually make it more difficult/tedious to get to the core functionality of what is occurring.
然而。 OOP的一大问题是当有人认为一切都应该是OOP时。这会产生很多问题。我的数据库中有88个表。我只有大约6个班级,也许我应该有大约10个班级。我绝对不需要88个班级。在我使用它的情况下,大多数情况下直接访问这些表是完全可以理解的,而OOP实际上会使得更难以/乏味地了解正在发生的事情的核心功能。
I believe a hybrid model of objects where useful and procedural where practical is the most effective method of coding. It's a shame we have all these religious wars where people advocate using one method at the expense of the others. They are both good, and they both have their place. Most of the time, there are uses for both methods in every larger project (In some smaller projects, a single object, or a few procedures may be all that you need).
我相信一个混合的对象模型,其中实用的有用和程序是最有效的编码方法。遗憾的是,我们拥有所有这些宗教战争,人们主张以牺牲其他方式为代价来使用一种方法。他们都很好,他们都有自己的位置。大多数情况下,在每个较大的项目中都有两种方法的用途(在一些较小的项目中,单个对象或几个程序可能就是您所需要的)。
#28
3
I don't care for reuse as much as I do for readability. The latter means your code is easier to change. That alone is worth in gold in the craft of building software.
我不像在可读性方面那样关心重用。后者意味着您的代码更容易更改。仅凭这一点在构建软件的过程中是值得的。
And OO is a pretty damn effective way to make your programs readable. Reuse or no reuse.
OO是一种非常有效的方法,可以使您的程序可读。重用或不重用。
#29
2
"The real world isn't "OO","
“现实世界不是”OO“,”
Really? My world is full of objects. I'm using one now. I think that having software "objects" model the real objects might not be such a bad thing.
真?我的世界充满了物体。我现在正在使用一个。我认为让软件“对象”模拟真实对象可能不是一件坏事。
OO designs for conceptual things (like Windows, not real world windows, but the display panels on my computer monitor) often leave a lot to be desired. But for real world things like invoices, shipping orders, insurance claims and what-not, I think those real world things are objects. I have a stack on my desk, so they must be real.
面向概念性事物的OO设计(如Windows,而不是真实世界的窗口,但我的计算机显示器上的显示面板)往往会留下很多不足之处。但对于现实世界的事情,如发票,运输订单,保险索赔和什么不是,我认为那些现实世界的东西都是对象。我的桌子上有一堆,所以它们必须是真实的。
#30
2
The point of OOP is to give the programmer another means for describing and communicating a solution to a problem in code to machines and people. The most important part of that is the communication to people. OOP allows the programmer to declare what they mean in the code through rules that are enforced in the OO language.
OOP的目的是为程序员提供另一种方法,用于描述和向机器和人员传递代码问题的解决方案。最重要的部分是与人们的沟通。 OOP允许程序员通过在OO语言中强制执行的规则来声明它们在代码中的含义。
Contrary to many arguments on this topic, OOP and OO concepts are pervasive throughout all code including code in non-OOP languages such as C. Many advanced non-OO programmers will approximate the features of objects even in non-OO languages.
与关于该主题的许多论点相反,OOP和OO概念在所有代码中都是普遍存在的,包括非OOP语言(如C语言)中的代码。许多高级非OO程序员即使在非OO语言中也会近似于对象的特征。
Having OO built into the language merely gives the programmer another means of expression.
将OO内置到语言中只会给程序员另一种表达方式。
The biggest part to writing code is not communication with the machine, that part is easy, the biggest part is communication with human programmers.
编写代码的最大部分不是与机器的通信,这部分很容易,最大的部分是与人类程序员的通信。
#1
24
There's no empirical evidence that suggests that object orientation is a more natural way for people to think about the world. There's some work in the field of psychology of programming that shows that OO is not somehow more fitting than other approaches.
没有经验证据表明,面向对象是人们思考世界的一种更自然的方式。在编程心理学领域有一些工作表明OO在某种程度上不比其他方法更合适。
Object-oriented representations do not appear to be universally more usable or less usable.
面向对象的表示似乎没有普遍的可用性或更少的可用性。
It is not enough to simply adopt OO methods and require developers to use such methods, because that might have a negative impact on developer productivity, as well as the quality of systems developed.
仅仅采用OO方法并要求开发人员使用这些方法是不够的,因为这可能会对开发人员的工作效率以及开发的系统质量产生负面影响。
Which is from "On the Usability of OO Representations" from Communications of the ACM Oct. 2000. The articles mainly compares OO against theprocess-oriented approach. There's lots of study of how people who work with the OO method "think" (Int. J. of Human-Computer Studies 2001, issue 54, or Human-Computer Interaction 1995, vol. 10 has a whole theme on OO studies), and from what I read, there's nothing to indicate some kind of naturalness to the OO approach that makes it better suited than a more traditional procedural approach.
这是来自2000年10月ACM通讯的“关于OO表示的可用性”。这些文章主要将OO与面向过程的方法进行比较。关于如何使用OO方法“思考”的人们进行了大量研究(Int.J. of Human-Computer Studies 2001,issue 54,或Human-Computer Interaction 1995,vol.10,OO研究的整个主题),从我读到的内容来看,没有任何迹象表明OO方法具有某种自然性,使其比传统的程序方法更适合。
#2
119
The real world isn't "OO", and the idea implicit in OO--that we can model things with some class taxonomy--seems to me very fundamentally flawed
现实世界不是“OO”,OO隐含的想法 - 我们可以用某种类别分类法来模拟事物 - 在我看来基本上是有缺陷的
While this is true and has been observed by other people (take Stepanov, inventor of the STL), the rest is nonsense. OOP may be flawed and it certainly is no silver bullet but it makes large-scale applications much simpler because it's a great way to reduce dependencies. Of course, this is only true for “good” OOP design. Sloppy design won't give any advantage. But good, decoupled design can be modelled very well using OOP and not well using other techniques.
虽然这是事实并且已被其他人观察到(采用STL的发明者Stepanov),其余的都是无稽之谈。 OOP可能存在缺陷,它肯定不是银弹,但它使大规模应用程序变得更加简单,因为它是减少依赖性的好方法。当然,这只适用于“好”的OOP设计。邋design的设计不会带来任何好处。但好的,解耦设计可以使用OOP很好地建模,而不是很好地使用其他技术。
There are much better, more universal models (Haskell's type model comes to mind) but these are also often more complicated and/or difficult to implement efficiently. OOP is a good trade-off between extremes.
有更好的,更通用的模型(Haskell的类型模型浮现在脑海中),但这些模型通常也更复杂和/或难以有效实施。 OOP是极端之间的良好平衡。
#3
45
OOP isn't about creating re-usable classes, its about creating Usable classes.
OOP不是关于创建可重用的类,而是关于创建可用类。
#4
42
All too often, the class is used simply for its syntactic sugar; it puts the functions for a record type into their own little namespace.
这个课程常常仅用于语法糖;它将记录类型的函数放入它们自己的小命名空间中。
Yes, I find this to be too prevalent as well. This is not Object Oriented Programming. It's Object Based Programming and data centric programing. In my 10 years of working with OO Languages, I see people mostly doing Object Based Programming. OBP breaks down very quickly IMHO since you are essentially getting the worst of both words: 1) Procedural programming without adhering to proven structured programming methodology and 2) OOP without adhering to to proven OOP methodology.
是的,我发现这也太普遍了。这不是面向对象的编程。它是基于对象的编程和以数据为中心的编程。在与OO Languages合作的10年中,我发现大多数人都在进行基于对象的编程。 OBP很快崩溃了恕我直言,因为你基本上得到了两个词中最糟糕的一个:1)程序编程没有遵循经过验证的结构化编程方法和2)OOP而不遵守经过验证的OOP方法。
OOP done right is a beautiful thing. It makes very difficult problems easy to solve, and to the uninitiated (not trying to sound pompous there), it can almost seem like magic. That being said, OOP is just one tool in the toolbox of programming methodologies. It is not the be all end all methodology. It just happens to suit large business applications well.
完成OOP是一件美好的事情。这使得非常难以解决的问题变得非常困难,对于那些没有经验的人(不要试图在那里听起来很夸张),它几乎看起来像是魔术。话虽这么说,OOP只是编程方法工具箱中的一个工具。它不是所有方法的全部。它恰好适合大型商业应用程序。
Most developers who work in OOP languages are utilizing examples of OOP done right in the frameworks and types that they use day-to-day, but they just aren't aware of it. Here are some very simple examples: ADO.NET, Hibernate/NHibernate, Logging Frameworks, various language collection types, the ASP.NET stack, The JSP stack etc... These are all things that heavily rely on OOP in their codebases.
大多数使用OOP语言的开发人员都在使用他们日常使用的框架和类型中完成的OOP示例,但他们并没有意识到这一点。下面是一些非常简单的示例:ADO.NET,Hibernate / NHibernate,Logging Frameworks,各种语言集合类型,ASP.NET堆栈,JSP堆栈等......这些都是在代码库中严重依赖OOP的所有东西。
#5
32
Reuse shouldn't be a goal of OOP - or any other paradigm for that matter.
重用不应该是OOP的目标 - 或者任何其他范例。
Reuse is a side-effect of an good design and proper level of abstraction. Code achieves reuse by doing something useful, but not doing so much as to make it inflexible. It does not matter whether the code is OO or not - we reuse what works and is not trivial to do ourselves. That's pragmatism.
重用是良好设计和适当抽象级别的副作用。代码通过做一些有用的事情来实现重用,但却没有做到让它变得不灵活。代码是否为OO并不重要 - 我们重用可行的方法,而不是自己做的微不足道。这是实用主义。
The thought of OO as a new way to get to reuse through inheritance is fundamentally flawed. As you note the LSP violations abound. Instead, OO is properly thought of as a method of managing the complexity of a problem domain. The goal is maintainability of a system over time. The primary tool for achieving this is the separation of public interface from a private implementation. This allows us to have rules like "This should only be modified using ..." enforced by the compiler, rather than code review.
OO作为一种通过继承重用的新方法的思想从根本上是有缺陷的。正如您所注意到的那样,LSP违规很多。相反,OO被恰当地认为是管理问题域复杂性的一种方法。目标是随着时间的推移系统的可维护性。实现这一目标的主要工具是将公共接口与私有实现分离。这允许我们使用编译器强制执行的规则,例如“只应使用...修改”,而不是代码审查。
Using this, I'm sure you will agree, allows us to create and maintain hugely complex systems. There is lots of value in that, and it is not easy to do in other paradigms.
使用它,我相信你会同意,允许我们创建和维护非常复杂的系统。这有很多价值,在其他范例中并不容易。
#6
28
Verging on religious but I would say that you're painting an overly grim picture of the state of modern OOP. I would argue that it actually has reduced costs, made large software projects manageable, and so forth. That doesn't mean it's solved the fundamental problem of software messiness, and it doesn't mean the average developer is an OOP expert. But the modularization of function into object-components has certainly reduced the amount of spaghetti code out there in the world.
关注宗教,但我会说你正在描绘现代OOP状态的过于严峻的画面。我认为它实际上降低了成本,使大型软件项目易于管理,等等。这并不意味着它解决了软件混乱的根本问题,并不意味着普通开发人员是OOP专家。但是,将功能模块化为对象组件确实减少了世界上意大利面条代码的数量。
I can think of dozens of libraries off the top of my head which are beautifully reusable and which have saved time and money that can never be calculated.
我可以想到几十个我头顶的图书馆,它们可以重复使用,节省了时间和金钱,无法计算。
But to the extent that OOP has been a waste of time, I'd say it's because of lack of programmer training, compounded by the steep learning curve of learning a language specific OOP mapping. Some people "get" OOP and others never will.
但是,就OOP浪费时间而言,我认为这是因为缺乏程序员培训,而且学习语言特定OOP映射的学习曲线陡峭。有些人“得到”OOP而其他人永远不会。
#7
21
I think the use of opaque context objects (HANDLEs in Win32, FILE*s in C, to name two well-known examples--hell, HANDLEs live on the other side of the kernel-mode barrier, and it really doesn't get much more encapsulated than that) is found in procedural code too; I'm struggling to see how this is something particular to OOP.
我认为使用不透明的上下文对象(在Win32中的HANDLEs,在C中的FILE *,用来命名两个着名的例子 - 地狱,HANDLEs生活在内核模式障碍的另一边,它真的没有得到在程序代码中也可以找到比封装更多的封装;我很难看到这对OOP来说是特别的。
HANDLE
s (and the rest of the WinAPI) is OOP! C doesn't support OOP very well so there's no special syntax but that doesn't mean it doesn't use the same concepts. WinAPI is in every sense of the word an object-oriented framework.
HANDLEs(以及WinAPI的其余部分)是OOP! C不能很好地支持OOP,因此没有特殊的语法,但这并不意味着它不使用相同的概念。从各个方面来说,WinAPI都是面向对象的框架。
See, this is the trouble with every single discussion involving OOP or alternative techniques: nobody is clear about the definition, everyone is talking about something else and thus no consensus can be reached. Seems like a waste of time to me.
看,这是涉及OOP或替代技术的每一次讨论的问题:没有人清楚定义,每个人都在谈论其他事情,因此无法达成共识。对我来说似乎浪费时间。
#8
14
Its a programming paradigm.. Designed to make it easier for us mere mortals to break down a problem into smaller, workable pieces..
它是一种编程范例。旨在让我们的凡人更容易将问题分解成更小,更实用的部分..
If you dont find it useful.. Don't use it, don't pay for training and be happy.
如果你没有发现它有用..不要使用它,不要支付培训费用并且要开心。
I on the other hand do find it useful, so I will :)
另一方面,我发现它很有用,所以我会:)
#9
14
Relative to straight procedural programming, the first fundamental tenet of OOP is the notion of information hiding and encapsulation. This idea leads to the notion of the class that seperates the interface from implementation. These are hugely important concepts and the basis for putting a framework in place to think about program design in a different way and better (I think) way. You can't really argue against those properties - there is no trade-off made and it is always a cleaner way to modulize things.
相对于直接的程序编程,OOP的第一个基本原则是信息隐藏和封装的概念。这个想法导致类的概念将接口与实现分开。这些是非常重要的概念,也是建立框架的基础,以不同的方式和更好的(我认为)方式思考程序设计。你不能真正反对这些属性 - 没有做出权衡,它总是一种更简洁的方式来模块化。
Other aspects of OOP including inheritance and polymorphism are important too, but as others have alluded to, those are commonly over used. ie: Sometimes people use inheritance and/or polymorphism because they can, not because they should have. They are powerful concepts and very useful, but need to be used wisely and are not automatic winning advantages of OOP.
OOP的其他方面包括继承和多态也很重要,但正如其他人所提到的那样,这些方面通常被过度使用。即:有时人们使用继承和/或多态,因为它们可以,而不是因为它们应该具有。它们是强大的概念,非常有用,但需要明智地使用,而不是OOP的自动获胜优势。
Relative to re-use. I agree re-use is over sold for OOP. It is a possible side effect of well defined objects, typically of more primitive/generic classes and is a direct result of the encapsulation and information hiding concepts. It is potentially easier to be re-used because the interfaces of well defined classes are just simply clearer and somewhat self documenting.
相对于重复使用。我同意重复使用已超过OOP。这是明确定义的对象的可能的副作用,通常是更原始/通用的类,并且是封装和信息隐藏概念的直接结果。重新使用它可能更容易,因为定义良好的类的接口只是更简单,有点自我记录。
#10
12
The problem with OOP is that it was oversold.
OOP的问题在于它是超卖的。
As Alan Kay originally conceived it, it was a great alternative to the prior practice of having raw data and all-global routines.
正如Alan Kay最初设想的那样,它是原始数据和全球惯例的先前实践的一个很好的替代品。
Then some management-consultant types latched onto it and sold it as the messiah of software, and lemming-like, academia and industry tumbled along after it.
然后一些管理顾问类型锁定它并将其作为软件的救世主出售,并且类似于旅鼠,学术界和工业界随之而来。
Now they are lemming-like tumbling after other good ideas being oversold, such as functional programming.
现在,在其他好的想法被超卖之后,它们就像在功能性编程中一样翻滚。
So what would I do differently? Plenty, and I wrote a book on this. (It's out of print - I don't get a cent, but you can still get copies.)Amazon
那么我会做些什么呢?很多,我写了一本关于此的书。 (已经绝版 - 我没有得到一分钱,但你仍然可以获得副本。)亚马逊
My constructive answer is to look at programming not as a way of modeling things in the real world, but as a way of encoding requirements.
我的建设性答案是将编程看作是在现实世界中对事物进行建模的一种方式,而是作为编码需求的一种方式。
That is very different, and is based on information theory (at a level that anyone can understand). It says that programming can be looked at as a process of defining languages, and skill in doing so is essential for good programming.
这是非常不同的,并且基于信息理论(在任何人都能理解的水平上)。它说编程可以看作是定义语言的过程,这样做的技巧对于良好的编程至关重要。
It elevates the concept of domain-specific-languages (DSLs). It agrees emphatically with DRY (don't repeat yourself). It gives a big thumbs-up to code generation. It results in software with massively less data structure than is typical for modern applications.
它提升了领域特定语言(DSL)的概念。它强烈同意DRY(不要重复自己)。它给代码生成带来了很大的好感。它导致软件的数据结构比现代应用程序的典型数据少。
It seeks to re-invigorate the idea that the way forward lies in inventiveness, and that even well-accepted ideas should be questioned.
它旨在重新激发前进的道路在于创造性的想法,并且应该质疑即使是被广泛接受的想法。
#11
11
HANDLEs (and the rest of the WinAPI) is OOP!
HANDLEs(以及WinAPI的其余部分)是OOP!
Are they, though? They're not inheritable, they're certainly not substitutable, they lack well-defined classes... I think they fall a long way short of "OOP".
他们是吗?它们不是可继承的,它们肯定不是可替代的,它们缺乏明确定义的类......我认为它们远远没有“OOP”。
Have you ever created a window using WinAPI? Then you should know that you define a class (RegisterClass
), create an instance of it (CreateWindow
), call virtual methods (WndProc
) and base-class methods (DefWindowProc
) and so on. WinAPI even takes the nomenclature from SmallTalk OOP, calling the methods “messages” (Window Messages).
你有没有用WinAPI创建一个窗口?然后你应该知道你定义了一个类(RegisterClass),创建它的一个实例(CreateWindow),调用虚方法(WndProc)和基类方法(DefWindowProc)等等。 WinAPI甚至采用SmallTalk OOP的命名法,调用方法“消息”(Window Messages)。
Handles may not be inheritable but then, there's final
in Java. They don't lack a class, they are a placeholder for the class: That's what the word “handle” means. Looking at architectures like MFC or .NET WinForms it's immediately obvious that except for the syntax, nothing much is different from the WinAPI.
句柄可能不是可继承的,但是,Java中有最终版本。他们不缺课,他们是班级的占位符:这就是“句柄”这个词的含义。看看像MFC或.NET WinForms这样的架构,很明显,除了语法之外,与WinAPI没什么不同。
#12
11
Yes OOP did not solve all our problems, sorry about that. We are, however working on SOA which will solve all those problems.
是的,OOP没有解决我们所有的问题,对不起。然而,我们正致力于解决所有这些问题的SOA。
#13
10
OOP lends itself well to programming internal computer structures like GUI "widgets", where for example SelectList and TextBox may be subtypes of Item, which has common methods such as "move" and "resize".
OOP非常适合编程内部计算机结构,如GUI“小部件”,例如SelectList和TextBox可能是Item的子类型,它具有常见的方法,如“move”和“resize”。
The trouble is, 90% of us work in the world of business where we are working with business concepts such as Invoice, Employee, Job, Order. These do not lend themselves so well to OOP because the "objects" are more nebulous, subject to change according to business re-engineering and so on.
麻烦的是,我们90%的人在业务领域工作,我们正在处理发票,员工,工作,订单等业务概念。这些不适合OOP,因为“对象”更加模糊,可根据业务重新设计等进行更改。
The worst case is where OO is enthusiastically applied to databases, including the egregious OO "enhancements" to SQL databases - which are rightly ignored except by database noobs who assume they must be the right way to do things because they are newer.
最糟糕的情况是OO热情地应用于数据库,包括对SQL数据库的恶劣OO“增强” - 除了数据库noobs之外被正确忽略,他们认为他们必须是正确的做事方式,因为它们更新。
#14
10
In my experience of reviewing code and design of projects I have been through, the value of OOP is not fully realised because alot of developers have not properly conceptualised the object-oriented model in their minds. Thus they do not program with OO design, very often continuing to write top-down procedural code making the classes a pretty flat design. (if you can even call that "design" in the first place)
根据我审查代码和项目设计的经验,OOP的价值还没有完全实现,因为很多开发人员没有在他们的脑海中正确地概念化面向对象的模型。因此,他们不使用OO设计编程,经常继续编写自上而下的程序代码,使这些类成为一个非常扁平的设计。 (如果你甚至可以称之为“设计”)
It is pretty scary to observe how little colleagues know about what an abstract class or interface are, let alone properly design an inheritance hierarchy to suit the business needs.
观察同事们对抽象类或接口的了解程度是多么可怕,更不用说正确设计继承层次结构以满足业务需求。
However, when good OO design is present, it is just sheer joy reading the code and seeing the code naturally fall into place into intuitive components/classes. I have always perceived system architecture and design like designing the various departments and staff jobs in a company - all are there to accomplish a certain piece of work in the grand scheme of things, emitting the synergy required to propel the organisation/system forward.
然而,当存在良好的OO设计时,阅读代码并且看到代码自然地落入直观的组件/类中只是纯粹的快乐。我一直认为系统架构和设计就像设计公司中的各个部门和员工工作一样 - 所有这些都是为了完成宏观方案中的某项工作,从而发挥推动组织/系统前进所需的协同作用。
That, of course, is quite rare unfortunately. Like the ratio of beautifully-designed versus horrendously-designed physical objects in the world, the same can pretty much be said about software engineering and design. Having the good tools at one's disposal does not necessarily confer good practices and results.
当然,这很不幸。就像世界上设计精美的设计与可怕设计的物理对象的比例一样,软件工程和设计也是如此。拥有良好的工具并不一定能带来良好的实践和结果。
#15
9
Maybe a bonnet, lap or a tree is not a chair but they all are ISittable.
也许发动机罩,膝盖或树不是椅子,但它们都是ISittable。
#16
8
I think those real world things are objects
我认为那些现实世界的东西都是物体
You do?
What methods does an invoice have? Oh, wait. It can't pay itself, it can't send itself, it can't compare itself with the items that the vendor actually delivered. It doesn't have any methods at all; it's totally inert and non-functional. It's a record type (a struct, if you prefer), not an object.
发票有哪些方法?等一下。它不能自己付费,它不能自己发送,它无法与供应商实际交付的项目进行比较。它根本没有任何方法;它是完全惰性和无功能的。它是一种记录类型(结构,如果你愿意),而不是一个对象。
Likewise the other things you mention.
同样你提到的其他事情。
Just because something is real does not make it an object in the OO sense of the word. OO objects are a peculiar coupling of state and behaviour that can act of their own accord. That isn't something that's abundant in the real world.
仅仅因为某些东西是真实的并不能使它成为OO意义上的一个对象。 OO对象是状态和行为的特殊耦合,可以自行行动。这不是现实世界中丰富的东西。
#17
7
I have been writing OO code for the last 9 years or so. Other than using messaging, it's hard for me to imagine other approach. The main benefit I see totally in line with what CodingTheWheel said: modularisation. OO naturally leads me to construct my applications from modular components that have clean interfaces and clear responsibilities (i.e. loosely coupled, highly cohesive code with a clear separation of concerns).
我在过去9年左右一直在编写OO代码。除了使用消息传递之外,我很难想象其他方法。我看到的主要好处完全符合CodingTheWheel所说的:模块化。 OO自然地引导我从模块化组件构建我的应用程序,这些组件具有干净的界面和明确的职责(即松散耦合,高度内聚的代码以及明确的关注点分离)。
I think where OO breaks down is when people create deeply nested class heirarchies. This can lead to complexity. However, factoring out common finctionality into a base class, then reusing that in other descendant classes is a deeply elegant thing, IMHO!
我认为OO崩溃的地方是人们创建深层嵌套的类heirarchies。这可能导致复杂性。然而,将共同的功能分解为基类,然后在其他后代类中重用它是一个非常优雅的事情,恕我直言!
#18
7
In the first place, the observations are somewhat sloppy. I don't have any figures on software productivity, and have no good reason to believe it's not going up. Further, since there are many people who abuse OO, good use of OO would not necessarily cause a productivity improvement even if OO was the greatest thing since peanut butter. After all, an incompetent brain surgeon is likely to be worse than none at all, but a competent one can be invaluable.
首先,观察结果有点草率。我没有关于软件生产力的数据,也没有充分的理由相信它没有上升。此外,由于有许多人滥用OO,即使OO是花生酱以来最好的东西,使用OO也不一定能提高生产率。毕竟,一个不称职的脑外科医生可能会比没有人更糟糕,但一个称职的脑外科医生可能是非常宝贵的。
That being said, OO is a different way of arranging things, attaching procedural code to data rather than having procedural code operate on data. This should be at least a small win by itself, since there are cases where the OO approach is more natural. There's nothing stopping anybody from writing a procedural API in C++, after all, and so the option of providing objects instead makes the language more versatile.
话虽这么说,面向对象是一种不同的排列方式,将过程代码附加到数据上,而不是让程序代码对数据进行操作。这应该至少是一个小胜利,因为有些情况下OO方法更自然。毕竟,没有什么可以阻止任何人在C ++中编写程序API,因此提供对象的选项使语言更加通用。
Further, there's something OO does very well: it allows old code to call new code automatically, with no changes. If I have code that manages things procedurally, and I add a new sort of thing that's similar but not identical to an earlier one, I have to change the procedural code. In an OO system, I inherit the functionality, change what I like, and the new code is automatically used due to polymorphism. This increases the locality of changes, and that is a Good Thing.
此外,OO做得非常好:它允许旧代码自动调用新代码,无需更改。如果我有程序性地管理事物的代码,并且我添加了一个与之前的类似但不相同的新类型的东西,我必须更改过程代码。在OO系统中,我继承了功能,改变了我喜欢的内容,并且由于多态性而自动使用新代码。这增加了变化的位置,这是一件好事。
The downside is that good OO isn't free: it requires time and effort to learn it properly. Since it's a major buzzword, there's lots of people and products who do it badly, just for the sake of doing it. It's not easier to design a good class interface than a good procedural API, and there's all sorts of easy-to-make errors (like deep class hierarchies).
缺点是良好的OO不是免费的:需要时间和精力来正确学习它。由于它是一个重要的流行词,因此有很多人和产品做得很差,只是为了做到这一点。设计一个好的类接口而不是一个好的过程API并不容易,而且还有各种容易出错的错误(比如深层次的层次结构)。
Think of it as a different sort of tool, not necessarily generally better. A hammer in addition to a screwdriver, say. Perhaps we will eventually get out of the practice of software engineering as knowing which wrench to use to hammer the screw in.
将其视为一种不同的工具,通常不一定更好。比如锤子和螺丝刀。也许我们最终会从软件工程的实践中走出来,因为他知道用什么扳手敲击螺钉。
#19
6
@Sean
However, factoring out common finctionality into a base class, then reusing that in other descendant classes is a deeply elegant thing, IMHO!
然而,将共同的功能分解为基类,然后在其他后代类中重用它是一个非常优雅的事情,恕我直言!
But "procedural" developers have been doing that for decades anyway. The syntax and terminology might differ, but the effect is identical. There is more to OOP than "reusing common functionality in a base class", and I might even go so far as to say that that is hard to describe as OOP at all; calling the same function from different bits of code is a technique as old as the subprocedure itself.
但无论如何,“程序化”开发人员已经这样做了几十年。语法和术语可能不同,但效果相同。 OOP比“重用基类中的常用功能”还要多,我甚至可能会说很难将其描述为OOP;从不同的代码位调用相同的函数是一种与子过程本身一样古老的技术。
#20
6
@Konrad
OOP may be flawed and it certainly is no silver bullet but it makes large-scale applications much simpler because it's a great way to reduce dependencies
OOP可能存在缺陷,它肯定不是银弹,但它使大规模应用程序变得更加简单,因为它是减少依赖性的好方法
That is the dogma. I am not seeing what makes OOP significantly better in this regard than procedural programming of old. Whenever I make a procedure call I am isolating myself from the specifics of the implementation.
这就是教条。在这方面,我没有看到OOP比旧程序编程更好的原因。每当我进行程序调用时,我都会将自己从实现的细节中分离出来。
#21
6
To me, there is a lot of value in the OOP syntax itself. Using objects that attempt to represent real things or data structures is often much more useful than trying to use a bunch of different flat (or "floating") functions to do the same thing with the same data. There is a certain natural "flow" to things with good OOP that just makes more sense to read, write, and maintain long term.
对我来说,OOP语法本身有很多价值。使用试图表示真实事物或数据结构的对象通常比尝试使用一堆不同的平面(或“浮动”)函数用相同的数据做同样的事情更有用。对具有良好OOP的事物有一定的自然“流动”,这对于长期阅读,编写和维护更有意义。
It doesn't necessarily matter that an Invoice isn't really an "object" with functions that it can perform itself - the object instance can exist just to perform functions on the data without having to know what type of data is actually there. The function "invoice.toJson()" can be called successfully without having to know what kind of data "invoice" is - the result will be Json, no matter it if comes from a database, XML, CSV, or even another JSON object. With procedural functions, you all the sudden have to know more about your data, and end up with functions like "xmlToJson()", "csvToJson()", "dbToJson()", etc. It eventually becomes a complete mess and a HUGE headache if you ever change the underlying data type.
Invoice实际上并不一定是具有可以自己执行的函数的“对象” - 对象实例只是为了对数据执行函数而不必知道实际存在哪种类型的数据。可以成功调用函数“invoice.toJson()”,而无需知道“发票”是什么类型的数据 - 结果将是Json,无论它来自数据库,XML,CSV,还是其他JSON对象。使用过程函数,您突然必须了解有关数据的更多信息,并最终使用“xmlToJson()”,“csvToJson()”,“dbToJson()”等函数。它最终变得完全混乱,并且如果您更改基础数据类型,那将会非常头痛。
The point of OOP is to hide the actual implementation by abstracting it away. To achieve that goal, you must create a public interface. To make your job easier while creating that public interface and keep things DRY, you must use concepts like abstract classes, inheritance, polymorphism, and design patterns.
OOP的要点是通过抽象来隐藏实际的实现。要实现该目标,您必须创建一个公共接口。为了使您的工作更容易创建公共接口并保持干燥,您必须使用抽象类,继承,多态和设计模式等概念。
So to me, the real overriding goal of OOP is to make future code maintenance and changes easier. But even beyond that, it can really simplify things a lot when done correctly in ways that procedural code never could. It doesn't matter if it doesn't match the "real world" - programming with code is not interacting with real world objects anyways. OOP is just a tool that makes my job easier and faster - I'll go for that any day.
所以对我来说,OOP真正的首要目标是使未来的代码维护和更改更容易。但即使超越这一点,当以程序代码永远无法完成的方式正确完成时,它可以真正简化很多事情。如果它与“现实世界”不匹配并不重要 - 无论如何,用代码编程都不会与现实世界的对象进行交互。 OOP只是一种工具,使我的工作更轻松,更快 - 我会在任何一天都去做。
#22
5
@CodingTheWheel
But to the extent that OOP has been a waste of time, I'd say it's because of lack of programmer training, compounded by the steep learning curve of learning a language specific OOP mapping. Some people "get" OOP and others never will.
但是,就OOP浪费时间而言,我认为这是因为缺乏程序员培训,而且学习语言特定OOP映射的学习曲线陡峭。有些人“得到”OOP而其他人永远不会。
I dunno if that's really surprising, though. I think that technically sound approaches (LSP being the obvious thing) make hard to use, but if we don't use such approaches it makes the code brittle and inextensible anyway (because we can no longer reason about it). And I think the counterintuitive results that OOP leads us to makes it unsurprising that people don't pick it up.
不过,如果这真的令人惊讶,我不知道。我认为技术上合理的方法(LSP显而易见)难以使用,但如果我们不使用这种方法,它会使代码变得脆弱且无法表达(因为我们不能再对它进行推理)。而且我认为OOP导致我们采取违反直觉的结果会让人们不会惊讶于人们不会接受它。
More significantly, since software is already fundamentally too hard for normal humans to write reliably and accurately, should we really be extolling a technique that is consistently taught poorly and appears hard to learn? If the benefits were clear-cut then it might be worth persevering in spite of the difficulty, but that doesn't seem to be the case.
更重要的是,由于软件对于普通人来说已经基本上难以可靠和准确地编写,我们是否真的应该赞美一种一贯教导并且难以学习的技术?如果利益是明确的,那么尽管有困难,它仍然值得坚持,但似乎并非如此。
#23
5
@Jeff
Relative to straight procedural programming, the first fundamental tenet of OOP is the notion of information hiding and encapsulation. This idea leads to the notion of the class that seperates the interface from implementation.
相对于直接的程序编程,OOP的第一个基本原则是信息隐藏和封装的概念。这个想法导致类的概念将接口与实现分开。
Which has the more hidden implementation: C++'s iostreams, or C's FILE*s?
哪个有更隐蔽的实现:C ++的iostreams,或C的FILE * s?
I think the use of opaque context objects (HANDLEs in Win32, FILE*s in C, to name two well-known examples--hell, HANDLEs live on the other side of the kernel-mode barrier, and it really doesn't get much more encapsulated than that) is found in procedural code too; I'm struggling to see how this is something particular to OOP.
我认为使用不透明的上下文对象(在Win32中的HANDLEs,在C中的FILE *,用来命名两个着名的例子 - 地狱,HANDLEs生活在内核模式障碍的另一边,它真的没有得到在程序代码中也可以找到比封装更多的封装;我很难看到这对OOP来说是特别的。
I suppose that may be a part of why I'm struggling to see the benefits: the parts that are obviously good are not specific to OOP, whereas the parts that are specific to OOP are not obviously good! (this is not to say that they are necessarily bad, but rather that I have not seen the evidence that they are widely-applicable and consistently beneficial).
我想这可能是我为什么要努力看到好处的一部分:明显好的部分并不是OOP特有的,而OOP特有的部分显然不是很好! (这并不是说它们一定是坏的,而是我没有看到它们广泛适用且始终有益的证据)。
#24
5
In the only dev blog I read, by that Joel-On-Software-Founder-of-SO guy, I read a long time ago that OO does not lead to productivity increases. Automatic memory management does. Cool. Who can deny the data?
在我读过的唯一的开发博客中,我是那个Joel-On-Software-W创始人,我读过很久以前OO并没有提高生产力。自动内存管理。凉。谁可以否认这些数据?
I still believe that OO is to non-OO what programming with functions is to programming everything inline.
(And I should know, as I started with GWBasic.) When you refactor code to use functions,variable2654
becomes
variable3
of the method you're in. Or, better yet, it's got a name that you can understand,
and if the function is short, it's called
value
and that's sufficient for full comprehension.
When code with no functions becomes code with methods, you get to delete miles of code.
当没有函数的代码成为带方法的代码时,您可以删除数英里的代码。
When you refactor code to be truly OO, b
, c
, q
, and Z
become this
, this
, this
and this
. And since I don't believe in using the this
keyword, you get to delete miles of code. Actually, you get to do that even if you use this
.
当您将代码重构为真正的OO时,b,c,q和Z成为这个,这个,这个和这个。由于我不相信使用this关键字,因此您可以删除数英里的代码。实际上,即使你使用它,你也可以做到这一点。
I do not think OO is natural metaphor.
I don't think language is a natural metaphor either, nor do I think that Fowler's "smells" are better than saying "this code tastes bad." That said, I think that OO is not about natural metaphors and people who think the objects just pop out at you are basically missing the point. You define the object universe, and better object universes result in code that is shorter, easier to understand, works better, or all of these (and some criteria I am forgetting). I think that people who use the customers/domain's natural objects as programming objects are missing the power to redefine the universe.For instance, when you do an airline reservation system, what you call a reservation might not correspond to a legal/business reservation at all.
例如,当您进行航班预订系统时,您所谓的预订可能根本不符合法律/商业预订。
Some of the basic concepts are really cool tools
I think that most people exaggerate with that whole "when you have a hammer, they're all nails" thing. I think that the other side of the coin/mirror is just as true: when you have a gadget like polymorphism/inheritance, you begin to find uses where it fits like a glove/sock/contact-lens. The tools of OO are very powerful. Single-inheritance is, I think, absolutely necessary for people not to get carried away, my own multi-inheritance software not withstanding.What's the point of OOP?
I think it's a great way to handle an absolutely massive code base. I think it lets you organize and reorganize you code and gives you a language to do that in (beyond the programming language you're working in), and modularizes code in a pretty natural and easy-to-understand way.OOP is destined to be misunderstood by the majority of developers
This is because it's an eye-opening process like life: you understand OO more and more with experience, and start avoiding certain patterns and employing others as you get wiser. One of the best examples is that you stop using inheritance for classes that you do not control, and prefer the Facade pattern instead.Regarding your mini-essay/question
I did want to mention that you're right. Reusability is a pipe-dream, for the most part. Here's a quote from Anders Hejilsberg about that topic (brilliant) from here:
我确实想提一下你是对的。在大多数情况下,可重用性是一个梦想。以下是Anders Hejilsberg关于该主题(精彩)的引用:
If you ask beginning programmers to write a calendar control, they often think to themselves, "Oh, I'm going to write the world's best calendar control! It's going to be polymorphic with respect to the kind of calendar. It will have displayers, and mungers, and this, that, and the other." They need to ship a calendar application in two months. They put all this infrastructure into place in the control, and then spend two days writing a crappy calendar application on top of it. They'll think, "In the next version of the application, I'm going to do so much more."
如果你要求初级程序员编写一个日历控件,他们常常会自己想:“哦,我将编写世界上最好的日历控件!它将是日历类型的多态。它将有显示器,和mungers,以及这个,那个和另一个。“他们需要在两个月内发送日历应用程序。他们将所有这些基础设施放在控件中,然后花两天时间在其上面编写一个糟糕的日历应用程序。他们会想,“在下一个版本的应用程序中,我会做更多的事情。”
Once they start thinking about how they're actually going to implement all of these other concretizations of their abstract design, however, it turns out that their design is completely wrong. And now they've painted themself into a corner, and they have to throw the whole thing out. I have seen that over and over. I'm a strong believer in being minimalistic. Unless you actually are going to solve the general problem, don't try and put in place a framework for solving a specific one, because you don't know what that framework should look like.
一旦他们开始思考他们实际上将如何实现他们的抽象设计的所有其他具体化,然而事实证明他们的设计是完全错误的。而现在他们把自己画成了一个角落,他们不得不抛弃整个事物。我一遍又一遍地看到了。我坚信极简主义。除非你真的要解决一般问题,否则不要试图建立一个解决特定问题的框架,因为你不知道那个框架应该是什么样子。
#25
4
Have you ever created a window using WinAPI?
你有没有用WinAPI创建一个窗口?
More times than I care to remember.
比我记得的次数多。
Then you should know that you define a class (RegisterClass), create an instance of it (CreateWindow), call virtual methods (WndProc) and base-class methods (DefWindowProc) and so on. WinAPI even takes the nomenclature from SmallTalk OOP, calling the methods “messages” (Window Messages).
然后你应该知道你定义了一个类(RegisterClass),创建它的一个实例(CreateWindow),调用虚方法(WndProc)和基类方法(DefWindowProc)等等。 WinAPI甚至采用SmallTalk OOP的命名法,调用方法“消息”(Window Messages)。
Then you'll also know that it does no message dispatch of its own, which is a big gaping void. It also has crappy subclassing.
然后你也会知道它没有自己的消息发送,这是一个很大的空洞。它也有蹩脚的子类。
Handles may not be inheritable but then, there's final in Java. They don't lack a class, they are a placeholder for the class: That's what the word “handle” means. Looking at architectures like MFC or .NET WinForms it's immediately obvious that except for the syntax, nothing much is different from the WinAPI.
句柄可能不是可继承的,但是,Java中有最终版本。他们不缺课,他们是班级的占位符:这就是“句柄”这个词的含义。看看像MFC或.NET WinForms这样的架构,很明显,除了语法之外,与WinAPI没什么不同。
They're not inheritable either in interface or implementation, minimally substitutable, and they're not substantially different from what procedural coders have been doing since forever.
它们在接口或实现中都是不可继承的,最小的可替代性,并且它们与程序编码器一直在做的事情没有太大的不同。
Is this really it? The best bits of OOP are just... traditional procedural code? That's the big deal?
这真的吗? OOP的最佳位置只是......传统的程序代码?那是大问题?
#26
4
I agree completely with InSciTek Jeff's answer, I'll just add the following refinements:
我完全赞同InSciTek Jeff的回答,我只想添加以下改进:
- Information hiding and encapsulation: Critical for any maintainable code. Can be done by being careful in any programming language, doesn't require OO features, but doing it will make your code slightly OO-like.
- Inheritance: There is one important application domain for which all those OO is-a-kind-of and contains-a relationships are a perfect fit: Graphical User Interfaces. If you try to build GUIs without OO language support, you will end up building OO-like features anyway, and it's harder and more error-prone without language support. Glade (recently) and X11 Xt (historically) for example.
信息隐藏和封装:对于任何可维护代码都至关重要。可以通过在任何编程语言中小心,不需要OO功能来完成,但这样做会使您的代码略微类似于OO。
继承:有一个重要的应用程序域,所有这些OO是一种类型和包含 - 关系是完美契合:图形用户界面。如果您尝试在没有OO语言支持的情况下构建GUI,那么无论如何您最终都会构建类似OO的功能,并且如果没有语言支持,它将更难以且更容易出错。例如,Glade(最近)和X11 Xt(历史上)。
Using OO features (especially deeply nested abstract hierarchies), when there is no point, is pointless. But for some application domains, there really is a point.
使用OO功能(特别是深层嵌套的抽象层次结构),当没有意义时,是没有意义的。但对于某些应用领域,确实有一点意义。
#27
4
I believe the most beneficial quality of OOP is data hiding/managing. However, there are a LOT of examples where OOP is misused and I think this is where the confusion comes in.
我相信最有利的OOP质量是数据隐藏/管理。然而,有很多例子中OOP被滥用,我认为这是混乱的地方。
Just because you can make something into an object does not mean you should. However, if doing so will make your code more organized/easier to read then you definitely should.
仅仅因为你可以把东西变成对象并不意味着你应该。但是,如果这样做会使您的代码更有条理/更容易阅读,那么您绝对应该这样做。
A great practical example where OOP is very helpful is with a "product" class and objects that I use on our website. Since every page is a product, and every product has references to other products, it can get very confusing as to which product the data you have refers to. Is this "strURL" variable the link to the current page, or to the home page, or to the statistics page? Sure you could make all kinds of different variable that refer to the same information, but proCurrentPage->strURL, is much easier to understand (for a developer).
OOP非常有用的一个很好的实际例子是我在我们网站上使用的“产品”类和对象。由于每个页面都是一个产品,并且每个产品都引用了其他产品,因此您所引用的数据所引用的产品会非常混乱。这个“strURL”变量是指向当前页面,主页或统计页面的链接吗?当然,您可以制作引用相同信息的各种不同变量,但proCurrentPage-> strURL更容易理解(对于开发人员而言)。
In addition, attaching functions to those pages is much cleaner. I can do proCurrentPage->CleanCache(); Followed by proDisplayItem->RenderPromo(); If I just called those functions and had it assume the current data was available, who knows what kind of evil would occur. Also, if I had to pass the correct variables into those functions, I am back to the problem of having all kinds of variables for the different products laying around.
此外,将功能附加到这些页面更加清晰。我可以做proCurrentPage-> CleanCache();其次是proDisplayItem-> RenderPromo();如果我只是调用这些函数并让它假设当前数据可用,那么谁知道会发生什么样的邪恶。此外,如果我必须将正确的变量传递给这些函数,我回到了为不同产品提供各种变量的问题。
Instead, using objects, all my product data and functions are nice and clean and easy to understand.
相反,使用对象,我的所有产品数据和功能都很好,干净,易于理解。
However. The big problem with OOP is when somebody believes that EVERYTHING should be OOP. This creates a lot of problems. I have 88 tables in my database. I only have about 6 classes, and maybe I should have about 10. I definitely don't need 88 classes. Most of the time directly accessing those tables is perfectly understandable in the circumstances I use it, and OOP would actually make it more difficult/tedious to get to the core functionality of what is occurring.
然而。 OOP的一大问题是当有人认为一切都应该是OOP时。这会产生很多问题。我的数据库中有88个表。我只有大约6个班级,也许我应该有大约10个班级。我绝对不需要88个班级。在我使用它的情况下,大多数情况下直接访问这些表是完全可以理解的,而OOP实际上会使得更难以/乏味地了解正在发生的事情的核心功能。
I believe a hybrid model of objects where useful and procedural where practical is the most effective method of coding. It's a shame we have all these religious wars where people advocate using one method at the expense of the others. They are both good, and they both have their place. Most of the time, there are uses for both methods in every larger project (In some smaller projects, a single object, or a few procedures may be all that you need).
我相信一个混合的对象模型,其中实用的有用和程序是最有效的编码方法。遗憾的是,我们拥有所有这些宗教战争,人们主张以牺牲其他方式为代价来使用一种方法。他们都很好,他们都有自己的位置。大多数情况下,在每个较大的项目中都有两种方法的用途(在一些较小的项目中,单个对象或几个程序可能就是您所需要的)。
#28
3
I don't care for reuse as much as I do for readability. The latter means your code is easier to change. That alone is worth in gold in the craft of building software.
我不像在可读性方面那样关心重用。后者意味着您的代码更容易更改。仅凭这一点在构建软件的过程中是值得的。
And OO is a pretty damn effective way to make your programs readable. Reuse or no reuse.
OO是一种非常有效的方法,可以使您的程序可读。重用或不重用。
#29
2
"The real world isn't "OO","
“现实世界不是”OO“,”
Really? My world is full of objects. I'm using one now. I think that having software "objects" model the real objects might not be such a bad thing.
真?我的世界充满了物体。我现在正在使用一个。我认为让软件“对象”模拟真实对象可能不是一件坏事。
OO designs for conceptual things (like Windows, not real world windows, but the display panels on my computer monitor) often leave a lot to be desired. But for real world things like invoices, shipping orders, insurance claims and what-not, I think those real world things are objects. I have a stack on my desk, so they must be real.
面向概念性事物的OO设计(如Windows,而不是真实世界的窗口,但我的计算机显示器上的显示面板)往往会留下很多不足之处。但对于现实世界的事情,如发票,运输订单,保险索赔和什么不是,我认为那些现实世界的东西都是对象。我的桌子上有一堆,所以它们必须是真实的。
#30
2
The point of OOP is to give the programmer another means for describing and communicating a solution to a problem in code to machines and people. The most important part of that is the communication to people. OOP allows the programmer to declare what they mean in the code through rules that are enforced in the OO language.
OOP的目的是为程序员提供另一种方法,用于描述和向机器和人员传递代码问题的解决方案。最重要的部分是与人们的沟通。 OOP允许程序员通过在OO语言中强制执行的规则来声明它们在代码中的含义。
Contrary to many arguments on this topic, OOP and OO concepts are pervasive throughout all code including code in non-OOP languages such as C. Many advanced non-OO programmers will approximate the features of objects even in non-OO languages.
与关于该主题的许多论点相反,OOP和OO概念在所有代码中都是普遍存在的,包括非OOP语言(如C语言)中的代码。许多高级非OO程序员即使在非OO语言中也会近似于对象的特征。
Having OO built into the language merely gives the programmer another means of expression.
将OO内置到语言中只会给程序员另一种表达方式。
The biggest part to writing code is not communication with the machine, that part is easy, the biggest part is communication with human programmers.
编写代码的最大部分不是与机器的通信,这部分很容易,最大的部分是与人类程序员的通信。