TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Classes vs. Data Structures

311 点作者 Anchor将近 6 年前

28 条评论

DeathArrow将近 6 年前
People are starting to use data oriented design instead of OOP. Data oriented design doesn&#x27;t hide state, is generally faster and easier to comprehend as it doesn&#x27;t abstract too much.<p><a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=QM1iUe6IofM" rel="nofollow">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=QM1iUe6IofM</a> <a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=yy8jQgmhbAU" rel="nofollow">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=yy8jQgmhbAU</a> <a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=rX0ItVEVjHc" rel="nofollow">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=rX0ItVEVjHc</a>
评论 #20210523 未加载
Jach将近 6 年前
I guess this applies for Java and C++ style &quot;classes&quot;. This does not precisely apply to the first ANSI-standardized OOP system, Common Lisp&#x27;s. Standard classes do not own methods, instead methods are specializations of a generic function that stands alone and dispatches on the class types (or EQL values) of all its arguments.<p>I&#x27;d really like it if Uncle Bob eventually has his fill of Clojure and moves on to explore what Common Lisp built decades earlier, then blogs about that too.
评论 #20209717 未加载
评论 #20209701 未加载
评论 #20209159 未加载
评论 #20208825 未加载
评论 #20210048 未加载
hudon将近 6 年前
The claim that &quot;an object is a set of functions that operate on implied data elements&quot; has a strange corollary because of how in modern OO languages like Java or C#, there is no syntax or popular naming convention to tell the difference between a data structure and an Object. For example, in Java, a LinkedList object is actually not a linked list, it is a set of functions that operate on an implied linked list. If the system needed direct access to the data for whatever reason, we&#x27;d need to explicitly have a LinkedList data structure object that only contained the data (the values and their pointers), as well as a second class, the LinkedListOperator, that contains all the functions (add, first, etc.). Likewise, in the author&#x27;s examples, there&#x27;d be a Square class and a SquareOperator class.<p>I was going to say that Haskell addresses this by putting values in data types and behaviors in &quot;type classes&quot;, but then I remembered that functions can be values... which is now making me think that the reality is probably more abstract or complex than the author here is letting on.
评论 #20207167 未加载
评论 #20206732 未加载
评论 #20206840 未加载
评论 #20210477 未加载
评论 #20206976 未加载
justinpombrio将近 6 年前
The first set of points:<p>&gt; Classes make functions visible while keeping data implied. Data structures make data visible while keeping functions implied. &gt; Classes make it easy to add types but hard to add functions. Data structures make it easy to add functions but hard to add types.<p>is known as the Expression Problem <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Expression_problem" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Expression_problem</a>.<p>The last point:<p>&gt; Data Structures expose callers to recompilation and redeployment. Classes isolate callers from recompilation and redeployment.<p>is only somewhat true. I <i>suspect</i> it would be more accurate to say that it&#x27;s a matter of indirection: static dispatch isolates callers from recompilation; static dispatch exposes callers to recompilation; calling a function pointer isolates callers from recompilation; calling a function directly exposes callers to recompilation. (All of this in statically typed languages.) Though this isn&#x27;t my area of expertise. Perhaps someone else knows more? [Edit: sounds like these &quot;expose&quot; cases often don&#x27;t cause recompilation either.]
评论 #20207431 未加载
RcouF1uZ4gsC将近 6 年前
&gt;OK, OK. I get it. The functions that operate on the data structure are not specified by the data structure but the existence of the data structure implies that some operations must exist.<p>This reminds me of Linus&#x27;s quote:<p>&quot;<p>I&#x27;d also like to point out that unlike every single horror I&#x27;ve ever witnessed when looking closer at SCM products, git actually has a simple design, with stable and reasonably well-documented data structures. In fact, I&#x27;m a huge proponent of designing your code around the data, rather than the other way around, and I think it&#x27;s one of the reasons git has been fairly successful (<i>).<p>(</i>) I will, in fact, claim that the difference between a bad programmer and a good one is whether he considers his code or his data structures more important. Bad programmers worry about the code. Good programmers worry about data structures and their relationships.<p>&quot;<p><a href="https:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;193245&#x2F;" rel="nofollow">https:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;193245&#x2F;</a>
评论 #20222587 未加载
评论 #20207308 未加载
gugagore将近 6 年前
This conversation reminds me of <a href="https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Expression_problem" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Expression_problem</a> .<p>I don&#x27;t understand: &quot;but the existence of the data structure implies that some operations must exist.&quot;<p>Grounding it out to a specific data structure, the existence of `List` implies that e.g. `sort` exists?<p>That direction makes less sense than `sort` implies the existence of e.g. `List`(something to be sorted).
评论 #20206553 未加载
评论 #20207871 未加载
评论 #20206995 未加载
725686将近 6 年前
Maybe a little tangential but it immediately came to my mind Alan Perli&#x27;s quote: &quot;It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures.&quot; I think I first heard this from Rich Hickey and made so much sense.
h8liu将近 6 年前
What the author calls &quot;objects&quot; (or &quot;classes&quot;) is really often just &quot;interfaces&quot;.<p>&gt; An Object is a set of functions that operate upon implied data elements<p>If this is replaced with:<p>&gt; An Interface is a set of functions, often operate upon implied some implied data elements (but not necessary).<p>Everything in the article will probably be less confusing.
F_J_H将近 6 年前
And while the discussion takes place and the debate rages between classes vs. data structures, there&#x27;s some poor analyst or data scientist who just needs access to the damned data to load it into a pandas data frame to do things that those designing the objects and data structures never dreamed of in the first place...
atoav将近 6 年前
Interesting read. What immediately sprung to my mind was Rust&#x27;s Trait system which sort of manages to give you the best of both worlds. With Traits you can implement common behaviour&#x2F;functions for multiple datastructures.<p>When I started using Rust I wasn’t used at all to seperate data and behaviour that strictly, but it makes sense. OOP paradigms were still hardwired in my head so the hardest part was actually <i>wanting</i> to do it in that decoupled way. Something about a car object that has wheel objects and a car.drive() function gives you a good feeling as a programmer, but sometimes it is more effective to stay with the data structure and describe the car as a struct of vectors which implement a <i>Driveable</i> trait..
skybrian将近 6 年前
Thinking about client-server architecture (for example, a database) can clarify things.<p>Encapsulation means you never have the canonical data. The server is the system of record. You can get data back in response to queries, perhaps even a full data dump, but it&#x27;s a snapshot. You can also send commands to mutate data on the server. Typical applications aren&#x27;t allowed to do a complete replacement (restoring from backup).<p>On the other hand, data is better thought of as what&#x27;s going over the network. Messages consist of data. Encapsulation is almost meaningless; if you want to keep something private from the receiver, don&#x27;t include it in the message in the first place (or use encryption, maybe). Anyone reading the data has to be able to understand the format, or at least, ignore what they don&#x27;t understand.<p>In the degenerate case where the caller and implementation live within the same process, the same types often get used both for message transfer (in function arguments and return values) and storage. There is widespread &quot;cheating&quot; for performance reasons, and it can get confusing. For a transient process, it might not make sense to think in these terms at all. (Traditional Smalltalk used <i>persistent</i> images and client-server style encapsulation makes somewhat more sense there.)<p>You can also &quot;cheat&quot; by using the same schema for data transfer and storage, or having a trivial mapping between them. This can introduce unnecessary coupling, but there are systems where it works. (Consider that you can make a full clone of a git repo and it doesn&#x27;t encapsulate any data.)
hotBacteria将近 6 年前
I like the shapes problem because I actually encountered it and it made me think.<p>I&#x27;m not sure about the switch approach described in the post:<p><pre><code> function area(shape) switch shape.type case &quot;square&quot;: return shape.side ** 2 case &quot;circle&quot;: return 2 * PI * shape.radius case &quot;triangle&quot;: return ... case &quot;segment&quot;: return 0 case &quot;polygon&quot;: return ... ... case &quot;oval&quot;: return ... </code></pre> You can have a lot of cases, some of them requiring non trivial code... Eventually you write a function for each case and it&#x27;s more work than adding a method for each shape because you still need to write the switch...<p>Classes seem work better than structures here.<p>But then you want to handle intersections<p>The switch approach doesn&#x27;t seem realistic:<p><pre><code> function intersection(shapeA, shapeB) if(shapeA.type == &quot;circle&quot; AND shapeB.type == &quot;circle&quot;)... if(shapeA.type == &quot;circle&quot; AND shapeB.type == &quot;square&quot;)... if(shapeA.type == &quot;square&quot; AND shapeB.type == &quot;circle&quot;)... ...&#x2F;&#x2F;uh oh you have nShapes**2 cases to handle </code></pre> But java classes or not better: where do you define Circle-Square intersection? In Circle? In Square?<p>Even with multiple dispatch the solution is not ideal. You now have some things related to Circle (area, perimeter...) in the Circle.blub file, and intersection(Circle, Circle) wich only works with Circles is now in intersections.blub...<p>I don&#x27;t see a good solution and sometimes I feel like the problem is more with our tools (code in text files) rather than programming paradigms
评论 #20211906 未加载
评论 #20215473 未加载
_0w8t将近 6 年前
The dependency discussion is wrong. Changing code of a function does not lead to recompilation of callers in most static languages. So if one change circlePerimeter, only that has to be recompiled. But if one changes data structure, then the callers has to recompiled. But this is also true for objects. In C++ changing data typically leads to recompilation of both implicit and explicit data structures. Essentially objects and data structures behaves the same.
评论 #20207076 未加载
mannykannot将近 6 年前
<i>Why does every software example always involve shapes?</i><p>Because they allow us to avoid discussing the complications that arise when entities have lifetimes, over which, at different stages, different operations are meaningful.
评论 #20211246 未加载
solinent将近 6 年前
A class is fundamentally about implementing object semantics. This simply means everything (eg. all objects) are an instance of some class. It has methods which can be used to operate or communicate with other objects or itself.<p>Data-structures are put most simply as ways of organizing data. The organization of the data implies a specific layout--a way of representing your data as a table of integers, ie. in RAM.<p>After reading the article, I don&#x27;t see a meaningful distinction between objects and data structures. A data structure can be represented as an object, especially in OOP languages where it <i>must</i> be.<p>A general class doesn&#x27;t necessarily lay out its data in any particular way--which allows abstraction over the data representation of the class.<p>However, some classes are made which are designed in a manner which guarantees a certain data layout. std::vector with its contiguous memory requirement comes to mind.<p>To add to this, the c++ conception of a &quot;concept&quot; or haskell&#x27;s concept of a &quot;typeclass&quot;, or even a generic class, is really what this article is talking about. Or even Java or Go&#x27;s interfaces. There is absolutely no way to guarantee a specific data structure through an interface, typeclass, or concept, since they fundementally do not mention their data representation at all.
Aromasin将近 6 年前
I enjoy the authors &quot;question&#x2F;answer&quot; style of writing. I often find myself asking questions just like this when reading an article, and find that when the author isn&#x27;t &quot;question focused&quot; they never get answered. It seems that when the entire writing style pivots on the idea, the author forces themselves to consider more Q&#x27;s to pad out the content and, incidentally or otherwise, provide more A&#x27;s.
评论 #20221688 未加载
bendbro将近 6 年前
This doesn&#x27;t make sense to me: &quot;Right. Now consider the area function. Its going to have a switch statement in it, isn’t it?&quot;<p>Perhaps I am nitpicking, or perhaps I am reading this wrong, but I would not design the square data structure to have a perimeter function. The square data structure should just expose the data that describes a square (length, width). Adding higher abstractions (perimeter, etc) on top of the data structure only serves to create the trumped up problem later described in the dialog. The perimeter method should be defined in the Square class, where perhaps a &quot;StraightLinesOnlyPolygonMixin&quot; could define the perimeter method.<p>In general, I cannot see why a Data Structure would define computational methods. You are tightly coupling logic to the underlying data source, which is wrong when that logic obviously could apply to any underlying data source (I don&#x27;t care if my square is backed by RDB, S3, a hardcoded instance, etc) The perimeter method, and probably the Square class, should be the same.
评论 #20207777 未加载
评论 #20210169 未加载
steve-chavez将近 6 年前
&gt; Since the database schema is a compromise of all the various applications, that schema will not conform to the object model of any particular application.<p>Here it jumps to objects instead of database VIEWs, that can be tailored for each application. There&#x27;s no need for complex object models when you embrace the db and you don&#x27;t treat it as a dumb store.
mcguire将近 6 年前
&quot;<i>No, ORMs extract the data that our business objects operate upon. That data is contained in a data structure loaded by the ORM.</i>&quot;<p>Technically, ORMs are a set of waldos that you operate inside a glove box in order to manipulate the data in the DB without getting DB cooties on you.
tydok将近 6 年前
Classes vs Data Structures, or maybe Objects vs Data Structures, or maybe Classes vs Objects, or maybe Data vs Data Structures, or maybe Data vs State, or maybe Classes vs Types, or maybe OOP vs FP, or maybe I don&#x27;t know what I&#x27;m talking about...
micimize将近 6 年前
Seems to me that with the definitions given, structures and objects aren&#x27;t opposites, they&#x27;re corollaries.<p>A database table is both a data structure and a collection of functions for accessing&#x2F;manipulating it (SQL). An ORM maps between the &quot;Object Oriented&quot; objects and the &quot;Relational&quot; objects that are tables.<p>Interesting the author thinks about the the api exposed by a table as the &quot;data structure&quot; itself rather than an object. Pragmatically, we tend to refer to the &quot;objects&quot; at the lower level of abstraction as data structures. Is [...] a function that defines an array, or the array itself?
nfrankel将近 6 年前
Am I the only one who has trouble with the dialog form?
评论 #20210938 未加载
sdegutis将近 6 年前
This is really hard to follow and I&#x27;m not sure I&#x27;m understanding it the way he intended.<p>Correct me if I&#x27;m wrong, but he seems to be saying that, to avoid breaking consumers of your library often by changing the implementation, hide the implementation details behind classes, right?<p>This seems to be a common reaction to someone who experiments with the &quot;freedom of functional programming&quot; where that freedom means operating on and returning raw data structures that OOP usually hides behind private variables.<p>That&#x27;s still bad practice, even in code that heavily uses FP, and good code usually mixes FP and OOP properly, so that you&#x27;re given functions when you&#x27;re meant to have functions, and data when you&#x27;re meant to have data. This is how I&#x27;ve been writing JavaScript for a few years now, and it&#x27;s not how I&#x27;ve seen Java or Clojure usually written.
评论 #20206856 未加载
flakiness将近 6 年前
Was surprised how Uncle Bob getting better at trolling these days. He&#x27;s been provoking, but somewhere in recent years he turned himself to a troll. (Or he&#x27;s just talking to his audiences, who aren&#x27;t HN readers.)
mistrial9将近 6 年前
very interesting and worthwhile! Data has gravity; and data dependancies are more costly than code dependancies, are two lines that are current.<p>Objects may possibly have broader uses that what is described here (&quot;business data applications&quot;) but within the definition given, the description of Object and operations on object make a lot of sense. This post is worth re-reading a few times.
stupidcar将近 6 年前
Whenever I hear &quot;Socratic dialog&quot;, I reach for my revolver. Is there any other form of teaching so irritating and patronising? You might have a brilliant store of insight to impart, but if you insist on trying to do so via a twee, affected and unbelievable conversation with a Mary Sue wise professor, I&#x27;m going to write you off as insufferable before the fawning moron you have as proxy for your audience utters their first &quot;Oh, wow! So you mean that straw-man you just put in my mouth <i>isn&#x27;t</i> true?&quot;
评论 #20207884 未加载
评论 #20207669 未加载
评论 #20207863 未加载
评论 #20207502 未加载
评论 #20208726 未加载
评论 #20208356 未加载
评论 #20207746 未加载
评论 #20209094 未加载
评论 #20209019 未加载
评论 #20208361 未加载
评论 #20208130 未加载
评论 #20208593 未加载
评论 #20208062 未加载
评论 #20208116 未加载
评论 #20208183 未加载
bcp2384将近 6 年前
Not every language is class-based...
gowld将近 6 年前
When Uncle Bob discovers subclasses, friends, decorators, and mixins, his mind will be blown.