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

科技回声

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

GitHubTwitter

首页

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

资源链接

HackerNews API原版 HackerNewsNext.js

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

Getter-Setter Pattern Considered Harmful

42 点作者 gm6783 个月前

27 条评论

geophile3 个月前
This misses the main problem with get&#x2F;set methods.<p>In OO othodoxy, you aren&#x27;t supposed to make state public, because it violates encapsulation. If you want to modify your Point object to use polar coordinates instead of cartesian, then if you expose your cartesian state (x and y), then all the code that relies on x and y is now broken.<p>So what getX() and setX() do is allow your x and y fields to be encapsulated. Problem solved! Except that once you change to polar coordinates you have your choice of problems:<p>1) Find all the getX() and getY() uses, and rewrite the affected code to use getR() and getTheta(), since you are now using polar coordinates. In other words, you have <i>violated</i> encapsulation by having getX() and getY() methods, and your get&#x2F;set methodology hasn&#x27;t achieved anything.<p>2) Re-implement getX() and getY() in terms of polar coordinates. That&#x27;s doable. But do you also now have getR() and getTheta()? Why?<p>Having getFoo() and setFoo() methods for each field foo is this dumb idea that began, I think, with JavaBeans. It has nothing to do with OO as I understand it. The idea behind OO encapsulation is to separate your object&#x27;s behavior (the methods) from private state. You can change state at will as long as you maintain behavior. Mechanically adding behavior (get&#x2F;set methods) to track your private state has always been a stupid idea that has nothing to do with OO except to violate encapsulation.
评论 #43069528 未加载
评论 #43069744 未加载
评论 #43069640 未加载
评论 #43069565 未加载
评论 #43069916 未加载
评论 #43069884 未加载
评论 #43069774 未加载
easton3 个月前
C# has the with part as a language built in; we use it at work with our immutable objects.<p><pre><code> var y = x with { things I want to change } </code></pre> <a href="https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;csharp&#x2F;language-reference&#x2F;operators&#x2F;with-expression" rel="nofollow">https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-us&#x2F;dotnet&#x2F;csharp&#x2F;language-ref...</a>
评论 #43069288 未加载
评论 #43069200 未加载
samiv3 个月前
What terrible advice. Your public variables are so much easier to refactor if&#x2F;when your data changes when you have simple accessors methods around them. Having accessors for data have saved my ass multiple times when I&#x27;ve had to do things such as a) migrate the data transparently b) remove data and use computation instead c) debug reads or writes of data.<p>The last point, sure you can have a breakpoint on a memory address but if you have a getter&#x2F;setter method its trivial to put a breakpoint in there, but I bet that if you have to set a memory brekapoint you have to waste time googling how do that (at least with GDB)<p>Raw data POD type structs are useful but only when the scope is limited.
评论 #43069127 未加载
Doxin3 个月前
I feel like this is one of the things python got right. You can start off with plain old data:<p><pre><code> def Foo: def __init__(self, foo): self.foo=foo </code></pre> Use it in all the ways you like. If then later you discover a need for a getter&#x2F;setter type setup (because you&#x27;re now e.g. storing foo in a different format internally) you can switch without any of the code depending on the Foo class needing to change:<p><pre><code> def Foo: def __init__(self, foo): self.foo=foo @property def foo(self): return unmunge(self._foo) @foo.setter def foo(self, v): self._foo = munge(v) </code></pre> I&#x27;ll grant that the syntax is slightly wonky, but its <i>really</i> nice to not have to think about getter&#x2F;setters when initially designing a class. You can add them when and where you need them without breaking other code.
评论 #43141632 未加载
jmull3 个月前
I don&#x27;t think this kind of article is that helpful.<p>There are aspects of a valid point in there, but it&#x27;s buried and confused.<p>That builder pattern makes me sick to my stomach.<p>Also, it starts with claiming state is part of the problem with getters&#x2F;setters, but does not mention it again. (It seems to be conflating mutability and state, which, while often related in practice, are not necessarily that tightly coupled -- an immutable thing can nevertheless be state, and you can have mutability without introducing state. State is really about things that live beyond the immediate context&#x2F;scope. So really nothing to do with getter&#x2F;setter.)
评论 #43069976 未加载
giancarlostoro3 个月前
I always thought blank &#x2F; barebones getters and setters were kind of dumb and genuinely pointless, some obscure ceremonial thing that. C# added syntactic sugar for them.<p>If you are not validating any of the input you might as well just have a public variable.
评论 #43069078 未加载
awfulneutral3 个月前
This article sort of reads like they think everything should be immutable, which feels kind of dogmatic. Using `with` for everything by default seems like overkill. But in C#, lately I have been using `readonly and `init` wherever vars should not be changed after initialization, which is most of them tbh. For small, data-only objects that can easily be immutable and get passed around a lot, this makes sense to me as a way to avoid the kind of bugs they are talking about.
brap3 个月前
I’m on board with the With and Builder patterns where it makes sense, but the final suggestion to make the fields public is just bad advice.<p>The author recognizes that mutable state gives you a lot to worry about, which I agree with. But public mutable fields make it even worse. Getters and setters at least minimize the surface area and give you some control over mutability.<p>There are many reasons why this is not the common practice, people have learned these lessons before.
IgorPartola3 个月前
I find immutable state to be useful when appropriate. But sometimes you really do want mutability, and it is a feature. Performance of updating player.coordinates, ability to create temporary but potentially complex structures inside the function, lack of need to create a new immutable copy of a bank account’s ledger to add another transaction, all good reasons to allow mutability.<p>It seems that there are some people who really just think of everything as a state machine and want state transitions to happen only in very controlled and specific ways. And other people seem to focus more on how to organize frequently evolutions of mutable state in a way that makes it easy to reason about. I’m not sure if there is some sort of commonality to these approaches. Different parts of the industry maybe? Different exposure to Haskell?
评论 #43069963 未加载
vips7L3 个月前
This pattern is really only used with @Entity’s. Things that actually are mutable and rightfully need to be. With @Entity’s setters are exactly what you want because it allows you to add validation, and check error states before persisting.<p>Arguing immutability for the sake of immutability is considered harmful imo. Only make things immutable when they actually are immutable or when concurrency is at play (which it probably isn’t, 99% of all code is single threaded).
评论 #43069294 未加载
评论 #43073256 未加载
thecleaner3 个月前
This is weird. I use getter&#x2F;setter regularly for DynamoDB backed DTOs. This helps catch setters at the source of a problem before it gets persisted. Also the exceptions will help pinpoint code paths where these things can happen.
joaonmatos3 个月前
I agree with the article for the most part (except the last snippet where the author reverted to bare, mutable fields), but the point was very badly argued.<p>I think we really need to consider that sometimes you want a place to hold together data, and some other times you are encoding some behavioral trait, and prior to records Java did not have a way of distinguishing between them.<p>My rule of thumb is to avoid exposing data in behavioral classes, and prefer immutable patterns for data holders. But sometimes it&#x27;s not possible to not have setters (e.g. for builders and for JPA entities).
renewiltord3 个月前
Some decades ago as a child I read a Bjarne Stroustrup interview where he said you use those things to enforce invariants and if you don’t you keep access simple. In the intervening decades, I’ve found that when I have a new invariant I often need to confirm the call sites are compliant anyway as he says. So I just use that, keeping accessors only where required or where interface compliance syntactically requires it.<p><a href="https:&#x2F;&#x2F;www.artima.com&#x2F;articles&#x2F;the-c-style-sweet-spot" rel="nofollow">https:&#x2F;&#x2F;www.artima.com&#x2F;articles&#x2F;the-c-style-sweet-spot</a>
donatj3 个月前
&gt; Notice the subtle difference? Dropping those get prefixes for the access methods has significant benefits. Let&#x27;s think about it: What value was added by the prefix? Correct, none!<p>Methods and functions <i>do something</i> rather than <i>are something</i> so naming them as the action they complete seems much better form to me. 3 characters is a fair price for clarity.<p>&gt; Drop the getters and setters. They don&#x27;t add any value<p>They add the ability for the underlying object to change without breaking compatibility. This is particularly important on shared libraries where you are not going to be able to refactor every single call sight.<p>For instance we have an object in our model representing a building, we&#x27;ve gone through *three* different structures of what a building is, but we&#x27;ve managed to make those changes while maintaining compatibility through leaving deprecated methods that translate the calls.
ziofill3 个月前
I get it, immutability is nice. But doesn’t it come with memory and runtime overheads for having to create and store new objects?
评论 #43073166 未加载
the_arun3 个月前
For immutable objects you can use new ‘record’. Another option is to use Lombok which provides an elegant way for reducing code.
zevv3 个月前
Summary: X is bad. How to do something without X? Don&#x27;t do X
harpiaharpyja3 个月前
Missed the obvious: age should be replaced with date of birth from which an up-to-date age can always be calculated.
kleiba3 个月前
Only when you&#x27;re a Java programmer can you find that &quot;Builder&quot; suggestion attractive.
drivingmenuts3 个月前
is there anything out there that that someone does not consider harmful?
debeloo3 个月前
Reads like AI garbage.
shaftoe4443 个月前
.
评论 #43069181 未加载
x0hm3 个月前
OOP separates coders from craftsmen.
评论 #43069340 未加载
readthenotes13 个月前
I can&#x27;t count how many bugs I found and fixed by removing setters.<p>I avoided Spring for years because of its asinine favoring of setters over correct construction
mikenereson3 个月前
I dont agree with the post, but wait til you hear about `record`.
recursivedoubts3 个月前
please for the love of Anders Hejlsberg just add properties to the language already we&#x27;ve had JavaBeans for like a century now we just need properties like any sane language would have added please bro i promise bro i swear just add properties to the langauge so the expression is a valid right hand side and left hand side look at javabeans bro i promise it&#x27;ll be ok it&#x27;s not bad to admit that anders was right on this one it&#x27;ll be ok bro just add properties please bro no more builders just lets add properties bro
tempestrose3 个月前
This is a waste of time. No One I&#x27;ve ever seen uses getName.<p>It&#x27;s always name.<p>Also, most of this is useless overkill.<p>If I have, in this case, a person object, I&#x27;m doing two things with it. Displaying it. Editing it.<p>If displaying, who gives a crap of its mutable? If I&#x27;m editing it, why are you wasting memory making a copy?<p>This just makes life way more difficult in most business apps.<p>Sure, if you NEED this, go for it. But for everyday bog standard business apps? Get the hell away from me.
评论 #43069489 未加载
评论 #43070010 未加载