6 ms·
Are you seriously saying that the best code is an untestable mess of big God classes? Because in my experience this is by far the type of code written by inexpe
by tigershark 10y ago
Are you seriously saying that the best code is an untestable mess of big God classes?
Because in my experience this is by far the type of code written by inexperienced programmers.
Abstractions and interfaces are the best way to make a system testable and extensible and it has nothing to do with using a pattern just because you read about it in the gof book 5 minutes ago.
And using public fields in a non trivial project is a sure receipt for disaster.
- blablabla123 10y agoI think he is rather referring to cascades of function calls/types and "custom solutions". Of course abstractions are a great tool when used properly. Thinking of a best practice from Object oriented design: low coupling but high cohesion. When you use abstractions, you get low coupling. But like everything in life, also this has a price: you may need an extra line of code to instantiate the abstraction and sometimes have to write an extra getter because it's not perfect yet. That's a fine price to pay unless go you use way too many abstractions and they are nested deeply. It may have some aesthetics but it can be hell to debug and overly complicated to extend code. So that's why one must also focus on high cohesion. I really like the modern JavaScript way, the imports/requires are for low coupling and the build automation is for cohesion. Anyways, these things are best practices as well but not sure if the author took those into account... ;)
- et1337 10y ago> using public fields in a non trivial project is a sure receipt for disaster. This is just dogma. Every Python project in existence has 100% public fields. Some are disasters, some are beautiful. Only a Sith deals in absolutes.
- eximius 10y agoBetter than ugly, beautiful is. Better then implicit, explicit is. Better than complex, simple is. Better than complicated, complex is. Better than nested, flat is. Better than dense, sparse is. Counts, readability does. Special enough to break the rules, special cases are not. But beaten by practicality, purity is. Silently passed, an error should never be. Unless explicitly, is it silenced. In the face of ambiguity, the temptation to guess, refuse you must. One, preferably only one, way to do it, there should be. Not obvious, it might be. Better than never, is now. But often better than right now, is never. If hard to explain, bad it is. If easy to explain, good it may be. Namespaces are a honking good idea - more of them we should do! -- The Zen of Python, Yoda
- qwertyuiop924 10y agoNow those are some best practices I can live by.
- balnaphone 10y ago(an attempt to translate to standard english grammar, for the benefit of other non-native English readers, who may also struggle to parse this) Beautiful is better than ugly. Explicit is better then implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases are not special enough to break the rules. But purity is beaten by practicality. An error should never be silently passed. Unless it is silenced explicitly. You must refuse the temptation to guess in the face of ambiguity. There should be one, preferably only one, way to do it. It might not be obvious. Now is better than never. But never is often better than right now. It is bad if it is hard to explain. It may be good if it is easy to explain. Namespaces are a honking good idea - we should do more of them!
- cariaso 10y agoinstead of offering your own translation, we can instead go back to the original english. Run 'python -m this' and you will see The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than right now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
- kazinator 10y ago> Namespaces are a honking good idea - we should do more of them! That should be: english.namespaces english.verbs.are english.articles.a american.english.vernacular.adjective.honking ...
- tigershark 10y agoIf there are inexperienced programmers working on it, as in my preamble, then almost surely it is in whatever language that doesn't prohibit to mutate objects indiscriminately. In F#, Haskell and other languages that enforce immutability obviously it isn't a problem, in Python most surely it is.
- et1337 10y agoEh. Inexperienced programmers will find a way to screw things up somehow. Probably by over-engineering, like the original article describes.
- kilink 10y agoI think the advice is more relevant in the context of the specific language; it's not universal. In python you can go from attribute access to using a property (getter/setter) without breaking anything. The same is not true in a language like Java where obj.foo is always a direct field access distinct from calling a method like obj.getFoo(), so going from public fields to getters is not backwards compatible and can be painful.
- qwertyuiop924 10y agoHowever, it's still a simple enough change that you shouldn't build getter/setters unless you're already pretty sure it'll be changed. OTOH, if you're using a language with generated getter/setters (ruby, smalltalk, lisp), just do it.
- superbatfish 10y ago>In python you can go from attribute access to using a property (getter/setter) without breaking anything. True, but that should be avoided if possible. Python 'properties' violate the principal of "explicit is better than implicit". Once you realize "Oops, I need an accessor function here", the lazy programmer says "Aww, grepping for all uses of .foo and replacing them with .getFoo() will take 20 minutes. Instead, I'll just redefine it as a property and no one will notice." If you care about quality, go the extra mile: make it clear to the people reading your code that a function is being called. Properties are a kinda nice language feature, but they are so frequently misused that I think the language would have been better off without them. They encourage bad habits.
- sbov 10y agoUsing find & sed is not painful. I use getters and setters, but still think you will waste more time arguing about this issue, than leaving it be and finding out you have to change them down the line. Edit: also, especially for getters, I like my accessors to be simple accessors. Hiding too much code behind them can be unpleasantly surprising, so as they deviate further from accessors I like to rename them - e.g. CalculateXxxx rather than GetXxx. Fewer surprises. Given that, I potentially have an issue with continuing to call it GetXXX or SetXXX in the face of certain changes.
- qwertyuiop924 10y agoMake your code testable, but public fields are fine.
- MaulingMonkey 10y agoCode can be underabstracted, but it can also be overabstracted - and abstracted with the wrong abstractions. And fixing the latter sometimes involves a temporary stay at "untestable mess of big God classes" when you remove the bad abstractions to clear the way for creating better ones. Not because it's the best code - far from it - but because it's slightly less terrible code. > And using public fields in a non trivial project is a sure receipt for disaster. Ergo, all non trivial C projects are disasters? Well, maybe, but I disagree on the reasons. Language enforced encapsulation is a useful tool, but some people take it to the deep end and assume that if their math library's 3D vector doesn't hide "float z;" in favor of "void set_z(float new_z);" and "float get_z() const;" (one of which will probably have a copy+paste bug because hey, more stupid boilerplate code), they'll have a sure receipt for disaster. Which I suspect you'd agree is nonsense - but would also follow from reading your words a little too literally.
- tigershark 10y agoIn my experience, in quite big projects, people had a tendency to mutate objects in the wrong place and in the wrong reasons. A field encapsulated in a getter without setter certainly helps.
- chopin 10y agoThat would be a final field. But generally I agree with you and its by far the pattern I use most.
- kuschku 10y agoThe issue is, for example, if you have for example a class encapsulating a bunch of flags, and allowing the user to either set each flag seperately, or a bitfield representing all of it. In C, you might be able to do some magic, but in Java, you’ll need setters and getters there – you can’t even do final fields there. Luckily, in C#, you can just use accessors, and maybe in Java with Lombok, too.
- qwertyuiop924 10y ago
- bartread 10y agoI don't think that's seriously what he's saying. You've over-interpreted to project the "logical" extreme of the POV expressed on the author. This is a trope in online debate that needs to die.
- andrepd 10y ago>And using public fields in a non trivial project is a sure receipt for disaster. Why, though? Surely it's the programmers' job to access what they need and leave alone what the don't. As someone else said, Python has no concept of public/private and it works okay.
- jedmeyers 10y agoIf you make the statically typed field public you lose the ability to change the implementation without breaking the clients. (Getters/setters have the same problems, but not as pronounced). And no, you don't always have the ability to recompile everything that's using your code.
- colejohnson66 10y agoAn argument for properties are to hide the implementation details. It keeps idiots from changing variables they shouldn't (if they really want to, there's sometimes reflection), and it hides implementation detail variables from the autocomplete box.
- lmm 10y agoPython doesn't really "work okay" for ongoing projects. Framework updates become a 6-month migration job.
- ArkyBeagle 10y agoI've returned recently ( for domain-specific reasons ) to sets of (opaque) god-classes with good interfaces when needed. No state in a god-class is visible except through the interface. Since the domain requires a great deal of serialization, the interfaces are usually strings over that. In cases, it's even easier to just open a socket to the serialization interface. So far, I'm able to pub/sub periodic data streams, but it'd be pretty easy to add "wake me when" operators and such. It forces the use of one central table of names cross callbacks ( which can be grown dynamically ) but it's very, very nice to work with. YMMV. The domain is instrumentation and industrial control, which just fits this pattern nicely. All use cases can and are specified as message sequences.
- flukus 10y agoI've been using the delegation pattern a lot lately as a nice way to combine the best bits of god classes (few dependencies) with the best of SRP (small easy to test parts). This way A, B, C (and many others) only depends on X, the delegator (which exposes a number of interfaces for practically everything), but X depends on everything and the kitchen sink, X contains no real functionality.
- ArkyBeagle 10y ago"Delegator". Now I know what to call it :)