Hacker News new | past | comments | ask | show | jobs | submit login
FizzBuzz Enterprise Edition (github.com/enterprisequalitycoding)
135 points by hglaser on Dec 21, 2014 | hide | past | favorite | 49 comments



The sad part is that many Java programmers would probably not realise that this is supposed to be a parody, because there are even more ridiculous-looking things in real, "production" Java code:

http://ws.apache.org/xmlrpc/apidocs/org/apache/xmlrpc/server...

http://docs.spring.io/spring-framework/docs/2.5.x/api/org/sp... (this one is somewhat famous - maybe it wins the "most number of design patterns in a class name" award?)

The impression I get whenever I come across code like this is that its authors were more interested in "creating architecture" than solving a real problem - and creating many classes containing short methods whose only function is to create more objects or pass existing ones around is a particularly insidious form of busy-work.

GNU Hello (http://www.gnu.org/software/hello/ ) is basically the same sort of thing done to a Hello World program.


Don't forget InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonPainter (http://javadoc.bugaco.com/com/sun/java/swing/plaf/nimbus/Int...)


"Convenient proxy factory bean superclass for proxy factory beans that create only singletons."


I have the urge to find out if a well (or badly?) tuned Markov chain can generate functional enterprise java code; I know exactly enough java to be sure all those words in that order actually mean something, but not nearly enough to have any notion what, precisely, that is.


For those who haven't seen it:

http://www.classnamer.com/

The Spring-flavored generator has an extra DesignPatternFactoryMixin.

http://www.classnamer.com/index.html?generator=spring


I played with this idea too, and ended up with http://www.methodnamer.com/


Convenient


This was a lot funnier before GitHub introduced the current folder mechanics. Since you previously had to dig into each level.


And is not even the longest one seen so far in java land

    /src/main/java/com/seriouscompany/business/java/fizzbuzz/packagenamingpackage


They rejected my pull request to migrate their markdown docs to docbook.

https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...


While we appreciate the careful crafting that went into this pull request and regard XML as an excellent choice for documenting projects of Enterprise caliber, we feel that moving to Docbook version 5 is a rather hasty move. The version is brand new, and we are unable to convince stakeholders about its Enterprise-grade integrity and long-term prospects as a documentation platform.

Brilliant.


I was trained in Java, but I never had to do any Big Enterprise Java coding. Can anyone summarize why and when this style of development began?


A combination of wasteful architecture astronomy and legitimate need to divvy up absolutely mammoth line-of-business applications among teams with hundreds of members operating for years with wildly varying skill levels, often on different subsystems from different physical locations, with billions of dollars on the line. You can't let the least senior programmer in the Melbourne office bring down the bank if he screws up with something, so instead you make it virtually impossible for him to touch anything than the single DAO which he is assigned to, and you can conclusively prove that changing that only affects the operation of the one report for the admin screen of a tier 3 analyst in the risk management group for trans-Pacific shipping insurance policies sold to US customers.

The tradeoff is, historically, that you're going to have to hire a team of seven developers, three business analysts, and a project manager to do what is, honestly speaking, two decent engineers worth of work if they were working in e.g. Rails. This is a worthwhile tradeoff for many enterprises, as they care about risk much, much, much more than the salary bill.

(I spent several years in the Big Freaking Enterprise Java Web Applications salt mines. These days I generally work in Rails, and vastly prefer it for aesthetic and productivity reasons, but I'm at least intellectually capable of appreciating the advantages that the Java stack is sold as bringing to users. You can certainly ship enterprise apps in Rails, too, but "the enterprise" has a process which works for shipping Java apps and applying the same development methodology to e.g. a Rails app would result in a highly effective gatling gun for shooting oneself in the foot.)


I never understood what the 'risk' in architecture designs meant until your comment made me realize it is indeed meant for teams where you really cannot trust all team members (shudders). Thanks, I see now more clearly.


if the decision makers were truly smart, they would've asked to use a provable programming language like Coq, or at least haskell or something like that (i hear Ada is very popular in millitary software because of it's contract based programming).


Not true. It's very difficult to unlock a big budget when you have a small team. And with Coq or Haskell, you team won't be very big...

Also, ADA is _a bit_ popular, but not too much. Most of the code is still done in C because of the conformism. Object oriented programming is still considered like a dangerously modern move. The rules here are pretty hard and it's easier to fuck up the regulation than the code... (cough A330 Neo cough)


In other words, the bureaucracy of the code reflects the environment it was developed in.


In other words,

organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations

—M. Conway

(http://en.wikipedia.org/wiki/Conway%27s_law)


> I spent several years in the Big Freaking Enterprise Java Web Applications salt mines [...]

I had to re-read your comment twice as I thought that there exists an OTS ERP for salt production.

PS. The company I work for actually grows salt.


I wonder how did this evolve to be...

I remember (vaguely) the beginnings of Java, but not how it did end up in Enterprise and why it was loved so much there.


Initially, it aimed at replacing C++ (which it mostly achieved, for LOB apps). The primary market for Sun has always been the enterprise, so it was a natural target.

Then, when the web exploded, people found out that developing against a virtual machine could be safer and more predictable than developing against the operating system, so web-app servers were born. J2EE provided a certain degree of consistency, which other platforms did not have.

As platforms evolved, they tried to generalise their use-cases, which introduced a number of abstractions and forced decoupling; and because Java2 lacked support for a lot of introspection/metaprogramming features, you had to explicitly cover a lot of cases, leading to interfaces multiplying.

It didn't help that at the time, the "Pattern" movement was popularised and their tools (which are all about decoupling and introducing further levels of abstractions) became overused.


Why didn't the enterprise go with the "microservices architecture" (not current usage of microservices, but you get the idea). Considering that SOA was actually originally from Java land, wouldn't the idea of every team with their own code base more appealing to the bureaucracy? The programming version of compartment.


Thanks, that's what I was looking for.


"architecture astronomy" is my new funny-yet-insightful phrase of the week. Thanks!


I was briefly exposed to this doctrine at school, so I hope dropping the following buzzwords help: POJO, Java Persistent API, Java Enterprise Beans, Gang of Four Design Patterns


I love that there is a commit to 'remove redundant import'. https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...

Being enterprise software, the last thing they need in the codebase is clutter.


Well, someone probably had a stretch goal to clean up some of the static analysis warnings.


The sad part is that there is actually an advantage to abstracting out the printing of fizz and buzz, and that is it will be easier to test. But the authors didn't even swap in a testable printing strategy, they just changed System.out.


Some things it's better NOT to test, rather than create an overengineered mess to facilitate testing.

Sometimes a fuzzbuzz is just a fuzzbuzz. A.k.a: KISS, YAGNI, etc...


Send a pull request!



Yes, but since then, there has been a continual stream of updates, unit tests (shockingly, the original version had ZERO unit tests), expanded support for a variety of IDEs, and better code structure.

Also, they author finally got around to actually providing a proper pom.xml file.

Check the commit history for details.

If you're interested in contributing, there's definitely room for expanding the unit test coverage, and also instrumenting the build process to support a code coverage tool such as EMMA or Coberture. Also, I don't believe that the code has undergone a security audit, and I don't see any code reviews for many of the commits, which is distressing.

And documentation! The code does not support javadoc, and in fact, there are only two comments in the entirety of the nearly 1500 line code base!


> And documentation! The code does not support javadoc, and in fact, there are only two comments in the entirety of the nearly 1500 line code base!

This is just _so_ non-compliant with Best Practices that it reveals itself too easily as a parody.

Each class should at least have the default Eclipse comment telling you how to change the template for a new class file, and most methods should have auto-generated JavaDoc for the first version of the method which was written years ago, with nothing filled in.


The main thing I look for with FizzBuzz solutions in general is how many modulus operators are used. The junior end of the spectrum tends to use four (% 5 && % 3; % 5; % 3), while intermediate/seasoned developers will either use three (% 15; % 5; % 3), or two (storing % 5 and % 3 in variables, then comparing the combinations).

My personal preference in terms of demonstrating maintainable code is using two modulus operations with variables. However, I fully understand the argument that an additional % 15 is preferable compared to the overhead of storing two variables on each iteration. Both are valid approaches IMO, and the debate can roar on for eternity. Micro-optimizations and whatnot.

I just don't like to see four modulus operations, which IMO shows a lack of basic willingness or ability to refactor while coding. It's fine to initially write the four modulus operations, but if someone doesn't immediately catch the duplication and do something about it, it screams "I write code until it works and then move on without cleaning anything up."

Strangely enough, only once have I seen someone use the % 15 optimization and add a short comment along the lines of "// least common multiple, divisible by both 3 and 5". Spotting the optimization is nice; placing a short comment explaining why % 15 when the test is about % 5 and % 3 is a nice touch. Explains something that might not be immediately obvious to the next person coming to the code.

Aside: it astounds me how many people, when asked to write a short snippet of code during an interview, have basic formatting problems and inconsistent code style. I've seen two lines of code inside an if() block indented at different levels, with no excuse for "different opinions on formatting". Not a wrapped line continued on the next, but just two simple statements inexcusably indented at say 8 and 12 spaces. Don't call us, we'll call you...


How many zero-modulus solutions (and still using a loop, not just a long precomputed string) have you seen? In my experience, this is the rarest type. Of those who can write a correct FizzBuzz (which is already a pretty small fraction of the total candidates), I like to ask "how would you do this without any modulus" and very few of them can easily see the pattern that makes this possible.

Aside: it astounds me how many people, when asked to write a short snippet of code during an interview, have basic formatting problems and inconsistent code style.

If this is being done on paper or an absolutely "non-IDE" text editor then it's probably someone dependent on an IDE to do the right formatting for them. If they still do this in an auto-formatting IDE, it's probably a sign that they have no good idea of the structure/flow of the code.


What is the "optimal" answer you are looking for if you ask to solve it without modulus? Build modulus by hand, or using additional resetting counter variables?


Two counters, one that counts by 3 and one that counts by 5.


I forgot to mention the variation where you start with an empty string, and % 3 to append 'Fizz' then % 5 to append 'Buzz'. This is also an instant pass in my book (two modulus, no calculation variables), though I don't personally care for the "coincidence" that for this specific problem the two conditions combined happen to provide the end result.

Then again it is FizzBuzz and not FizzBuzzMozz, where numbers divisible by both 3 and 5 produce a string that cannot be concatenated by the individual 3 and 5. So to be fair, this solution is perfectly valid. :p


I know exactly what you mean by the "coincidence" and how taking advantage of it seems off somehow, but I suspect the original problem was written with that solution in mind.


Other reasons that solution puts me off a little:

1. You have a dangling check for empty string at the end to set to the current number if the string is empty after the Fizz/Buzz conditions. An "else" clause disguised as an "if" clause.

2. It's just messier to understand. "If % 3, append Fizz; if % 5, append Buzz" has four different outcomes: neither matches, first matches, second matches, both match. A newcomer to the code has to mentally separate out all possibilities (which basically requires re-scanning the same code four times). Whereas the "if, elseif, elseif, else" can be read over and understood with a single scan.


Here is an implementation in Python with only one operator

  # Inputs
  >>> i = range(1, 100)
  >>> d = [(15, 'FizzBuzz'), (5, 'Buzz'), (3, 'Fizz')]

  # Let's define some lambdas - calculation, test, reduction
  >>> c = lambda x, y: y[1] if (x % y[0] == 0) else x
  >>> t = lambda a, b:  a if type(a) is str else b
  >>> r = lambda e: reduce(t, e)

  # Now process
  >>> map(r, map(lambda x: map(lambda f: c(x, f), d), i))


Why would you need more than one?

(my version - https://gist.github.com/vai/4647768 )


This makes me hurt inside.



I don't get why all you kids love these obfuscation competitions. ;-)


"... necessary tools such as if-/else-statements and loops"

https://en.wikipedia.org/wiki/Array_programming


Enterprise programming is like Hadoop. Huge startup overhead, but once workers start up, progress shoots up at a pace faster than possible with less thought out systems.


Verbose way to express that a lot of enterprise Java code is verbose. I wish I had as much free time.


ahahahahahahahahaha nice :D




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

Search: