Hacker News new | past | comments | ask | show | jobs | submit login
Anti Patterns Catalog (c2.com)
120 points by infogulch on Dec 30, 2016 | hide | past | favorite | 54 comments



Anti-pattern: GasolinePoweredFlySwatter

Reaching for heavy and complex tools when a straightforward solution would have sufficed.

Example: Requiring JavaScript for a simple static site. Making a wiki as an SPA.


Wow I've just noticed what they've done to C2 Wikis. An amazing site and resource, and they had go to and JS framework it. It was looking a bit long in the tooth, sure, but couldn't they just have added a few lines of CSS?


The worst part is: it doesn't even look good/modern now. They should have gone with this:

http://bettermotherfuckingwebsite.com/

(excuse the profanity)


The original is much nicer, same URL without the "better".


Downvotes? The look of the original website (the URL without the "better" [1]) much closer resembles the original c2 wiki style. The CSS is not even needed in this case.

[1] http://motherfuckingwebsite.com


Not IMO. Better is better.


Came here to say this. Does anyone know whether there's an effort to port this to a sane wiki system?


Part of Ward Cunningham's roadmap is to make mirroring (even to other wiki implementations) much easier.

That said, given that he's the original inventor of the wiki, I'd say he's earned a bit of patience on our part. Let's wait and see where he's going with these ideas (some of which are: federation, bi-directional linking between wikis, forking & merging, transclusion, etc.), a bit longer before contemplating setting up a "classic" wiki with this content.


It sounds like the wiki was rewritten recently as a single page app which is what is causing the slowdown.

See https://github.com/WardCunningham/remodeling#remodeling which is linked from the footer of the wiki.


http://imode.gitlab.io/projects/c2/index.html

here's a dump of the entire wiki in WikiWikiWeb markup. if you can do anything with it, let me know.


What do you think of Pandoc? http://pandoc.org/

The two supported wiki markups:

- MediaWiki https://www.mediawiki.org/wiki/Help:Formatting

- TWiki http://twiki.org/cgi-bin/view/TWiki/TextFormattingRules

I wonder which one is the closest to WikiWikiWeb syntax.

Another cool stuff would be to put that in the gopherspace.


I actually tried pandoc + MediaWiki markup but it ended up quite consistent and not representing the original page.

ward's site actually contains the rules for deconstructing the JSON and translating it to HTML. I'll have a look at that when I have time.


> Making a wiki as an SPA.

Well, that's technically fine. However, the page should be a static document which was rendered on the server side and the other stuff should be loaded later and only when needed.

There is no reason why the initial render can't be done in <20 KB and <5 requests.


> However, the page should be a static document

SPAs are almost always not rendered server-side. They can be, but it's harder so they aren't.


Ironic isn't it?


What is SPA?



No Javascript required, but pages are in JSON instead of HTML.

http://c2.com/wiki/remodel/pages/[page_title] e.g. http://c2.com/wiki/remodel/pages/AntiPatternsCatalog

What is behind the obsession with JSON?

If JSON is nested too deep, memory is exhausted.

Why blindly put an entire structure of unknown size into memory? Just to parse some text.

Why not use something like netstrings?


My experience shows that almost all GoF design patterns, except singleton, are not useful at all in writing modern C++ software.

The singleton is really just about a language trick, it hardly means anything more than a global variable fit into C++'s class hierarchy.

I've been writing C++ in the past 1.5 years. All I have saw is design patterns being used forcefully and awkwardly. And there has not been a single instance where a pattern is used and improves the overall quality.

Such practices result into closely coupled class webs, which is hostile to testing, extremely difficult to understand and change; the worst, they easily causes circular dependency, which was once considered a norm in C++ code.

They also result into overengineerred interfaces, which gradually morphed into a "DoEverything" interface, like DoEverything(ActionOptions, RuntimeEnvironment). ActionOptions literally captures every options you can have on anything; and RuntimeEnvironment includes all data for the action to happen.

IMHO, C++ code is about as good as it can be, when it manages to achieve 2 things: 1. DAG in translation unit dependency. 2. Predominantly prefer composition to inheritance.

Plus, class access control (private/protected), and anonymous namespace should not be used to hide your implementation. That makes writing tests way too troublesome. And TBH, no one wants to abuse implementation details, unless the interface is bad or no comprehensive tests.


>They also result into overengineerred interfaces, which gradually morphed into a "DoEverything" interface, like DoEverything(ActionOptions, RuntimeEnvironment). ActionOptions literally captures every options you can have on anything; and RuntimeEnvironment includes all data for the action to happen.

Also known as a function on the IO monad. The people who were writing that might have a good time with Haskell.


I never really got the whole public/private thing. If you want to only expose certain functionalities, that's what the interface does. Making things private just hides things that are potentially nice hooks for testing or whatever.


> I never really got the whole public/private thing.

It's about encapsulation and class invariants. Public methods must preserve them, private methods can break them temporarily. You get a prepackaged component and you're prevented from introducing bugs into the component from the outside of the component.

Take std::vector, for example. By keeping implementation details (pointer to element storage and element count) private, you prevent users of the class to accidentally shoot themselves in the foot by, say, changing the element count directly.

You could use interfaces, but for that you have to use virtual functions: Objects have to be created dynamically and you have to handle pointers or references instead of values.


I understand what it's used for, i just feel like there's a more elegant way to do it.


The assumption is that your public members are your interface. Anything private is an internal implementation detail, possibly subject to future change or replacement.

Thorough testing of the public methods should end up calling all of the private methods. Of course, that's a best case scenario. In C++ at least, it'd be an option to make a testing class that's a friend of the class it tests. Then you could test the private members individually.


I think almost all modern languages end up with granting (unit) testing code free access to everything. The idea of testing only the public interface is about an unique snow flake only meaningful in C++ design, and was never a viable practice at all. Otherwise, I'd say at least one other language follow the similar approach...


Are you just complaining about a lack of introspection to get around access controls? Friend classes are better for encapsulation than introspection is.


We published a small collection of Python-related anti-patterns a while ago under a creative commons license, feel free to check it out:

http://docs.quantifiedcode.com/python-code-patterns/


Are those also considered anti-patterns, or simply "bad practices"? The examples in the article seem to have a wider scale than the ones mentioned in your collection.

My question is, where is the line the line between an anti-pattern or simply a "bad practice", or if they are the same?


Probably more bad practice by that definition, though for me the two concepts are very similar. I think the original article aimed more at process and large scale patterns, where our book aims more at small scale patterns.


anti-pattern would be: "commonly reinvented bad solution to a recurring problem" (paraphrasing wikipedia)


Anti-patterns can be copied as well as reinvented. Also, some can manifest simply through developers' inattention rather than being a deliberate reinvention, such as:

* Big Ball of Mud

* Creeping featuritis

* Copy Pasta


There's patterns and then there's design patterns. The latter is more high-level, as you're thinking.



I guess there can be an antipattern opposite to NotInventedHere, where developers don't want to solve small problems, only reuse existing libraries that already address the problem in hand. I guess this is most noticeable in the javascript world.


I've seen it called "Never Invent Here"


I feel like this list has been designed in such a way that it is not possible to create any code, without implementing an example from the list.

When you make a list this long, you're attempting to cast a wide net over most conditions, if not trying for total coverage by including catch-all buckets.

Meanwhile, it feels slightly impossible to ask anyone to write code at all, without having them complain about something.

The only lesson I can glean from this is that every project requires a compromise of combining abominations with idealized perfection, and that transitory human moods and emotions have more effect on programming tastes, than actual practicality.


This is the case with most such lists of verboten practices. It's good to know the general rules, but it's also important to know when your situation justifies breaking them. Competency is all about good judgment.


http://wiki.c2.com/?PassingNullsToConstructors

Is it even worth having such pages in a wiki? Is this a catalog of antipatterns or empty templates?


I don't know which is funnier, the inaccessibility of the "anti-pattern" website in general which is bitching about inaccessibility of applications, or the fact that the 'constructor' (loosely) for serving you that page is clearly 'null'~


What's NULL? Switch to the pure FP world. Haven't had a NPE in years, because we never create/pass/consume NULL.


The wiki is very slow since the upgrade.


At least it works now. There was a hot minute there where they'd decided that the `fetch` API was a required feature and didn't polyfill it, totally breaking the site in browsers that lacked the feature.


[flagged]


> At the risk of significant downvoting

This breaks the HN guidlines: https://news.ycombinator.com/newsguidelines.html. Please edit downvote-baiting out of your comments here.


No, and that's ridiculous. Your rule says, "Please don't bait other users by inviting them to downvote you or proclaim that you expect to get downvoted."

I didn't bait anyone nor did I say I expected it. I said I was risking downvotes by having a contrarian opinion. Expectation and acknowledgement of risk are not identical.

In any case, you've won dang. While I've been a user here for nearly four years, you've really convinced me that participating in this community is wasted effort. Feel free to delete this account. I won't be back.


I agree with you that this isn't science, but I also don't see how they're portraying it as such, so your comment sounds unnecessarily hostile.


Well, actually...

Antipatterns are on rather firmer academic ground than the guy at the airport barstool. Antipatterns are simply a negative version of design patterns. Design patterns in software started with the book Design Patterns: Elements of Reusable Object Oriented Software (aka Gang of Four or GoF), one of the greatest classic works in software engineering. GoF was itself based on the book A Pattern Language, by Christopher Alexander, a classic of the architectural field.

Alexander came up with the idea of a "pattern language" to describe patterns in architecture, a formal structure for observable phenomena. The GoF reused pattern language in a formal way to describe software patterns. Part of the pattern language describes how to implement the pattern. Antipatterns first appeared in the book Antipatterns: Refactoring Software, Architectures, and Projects in Crisis. Again, pattern language was used, including patterns for solving the problems caused by the antipattern.

So yes, this is rigorous. Not math-rigorous, but rigorous.


The kinds of things listed on the link have to do with project management and anecdotes about human interactions on teams that happen to be building software. You can try to tie this intellectually to more legitimately thought-out ideas, but you're stretching its content enormously. It's a farce to call this kind of thing "rigorous."


However, it should be noted that Design Patterns as we know them have very little to do with those described by Alexander: They are the same in name only.


The structure for describing patterns is the same.


> all their little named terms

Whose---The authors of the articles', or "HNers"'?


Exactly. This is just compulsive obsession over classifying (imaginary) things. The worst part is, that many of these are probably somewhat valid observations. I would actually be happy to read well-written book of short anecdotes about "how a bad decision was made and what happened" related to software development. It's not like such books (about life in general) do not exist already, but it is always treated as fiction/publicistic literature (as it should be). Trying to make a list of these and name these (especially in stupid camel-case manner, that does not contribute to readability at all), and assign "properties" ("Type", "Root Causes", "Refactored Solution") to them — it is just stupid and counter-productive.


Sheesh, people, did they kick your dog or something?

They're just some people trying to help others by identifying some common problems they've encountered. Sure, the presentation might not be the best (though most of them don't have "properties", they're just a discussion), but does it really merit the epithets?

Also, regarding the camel case, that's just the Wiki's own linking format. I agree it wasn't the best decision, but considering this is the first invented Wiki ever, surely Ward can be excused a bad decision or two?


What a mess of a list. Management, coding, architectural, and uncategorized "anti-patterns" lumped together. I bet many of them are just from somebody blowing off steam.


shameless plug: there is an entire dump of the c2 wiki at http://imode.gitlab.io/projects/c2/index.html

it's still in plaintext, i.e WikiWikiWeb markup format, and I haven't touched it in a while. if anybody knows how to convert this to HTML, let me know and I'll batch-convert it.

ward, your site is taking a down-hill turn. stop with this remodeling and go back to the static site, please.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: