๐Ÿ‘คlbarrow๐Ÿ•‘12y๐Ÿ”ผ29๐Ÿ—จ๏ธ54

(Replying to PARENT post)

YAGNI is well and good for certain types of problems, especially prototypes and proofs-of-concept--essential to succeeding, even.

However, the very second you know for sure that you'll need to expand the system, you need to stop and pull on your big-kid pants and do some design. Any fool can keep throwing code at slight variations of a problem until they're buried in spaghetti (and many do!), but people that actually know what the hell they're doing will bust out the abstraction hammer when it becomes clear that it's prudent (and not a moment before).

Generally, once I've had to solve a similar problem three times it's time to refactor. Once is providence, twice is coincidence, but three times suggests that things need to be designed.

EDIT:

The author's example is particularly poor. A dog, chicken, and cat all need to move, follow a player, interact with the game world, update, spawn, and die. It makes perfect sense to have a Pet class handle this glue entity lifecycle code, and then to specialize a subclass to override the rendering or update code.

There are cases where YAGNI is alive and well, but this example simply isn't it.

๐Ÿ‘คangersock๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

I've worked on some big, mature code bases, and I've always appreciated it when other people believe in YAGNI. It tends to result in relatively simple code with just enough complications to support the features which actually exist.

In theory, it would be nice if the code included appropriate hooks and abstractions. But in practice, it's often quite hard to guess where those hooks should be, and which aspects of the code should be abstracted. And since the abstractions are based on hypothetical designs, they're very often useless.

Basically, I'd rather maintain over-simplistic code that implements a few features well than code that has been prematurely generalized to support half a dozen features which don't exist yet. All too often, the generalizations are wrong, or simply get in the way of other features I'm trying to add.

Unfortunately, YAGNI is one of those rules that requires common sense to apply well. It works best as a sanity check for an already-experienced programmer: "Really? Do I actually need a whole new set of abstract interfaces here? Or can it wait?" If a programmer is totally lacking in taste and judgement, YAGNI won't save them by itself.

๐Ÿ‘คekidd๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

I'll confess, I don't understand YAGNI.

I think I've been tainted by too many counter-examples: seeing a piece of code that was specially written for a very narrow and specific use case, and needing to extend it to some scenario that the original author did not envision. If the author hadn't been thinking in terms of re-use and extensibility ("because they ain't gonna need it"), it gets frustrating and regression-prone.

In other words, you ain't gonna need it, until you eventually do. Lazy programmers shouldn't be excused for dismissing maintainability with a simple catch phrase.

๐Ÿ‘คasveikau๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

I can't really agree, although its hard to argue against a contrived example and a general rule that is almost a tautology (don't write code you don't need).

A lot of times "architecture astronauting" is simply good separation of concerns. To take the Dog example: there is a lot of code necessary to get a Dog into the world of minecraft that isn't specific to the concept of Dog at all, such as drawing itself, keeping track of its state in the world, etc. These are the types of concerns you would want in a base class of Dog and potential Cats and Chickens. This is something that should be factored out, not because you may eventually make a Cat, but because those concerns have no connection to the concept of Dog at all. Keeping such code together will just make comprehending the actual Dog specific code harder.

๐Ÿ‘คhackinthebochs๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

A thousand times yes. I totally agree but this is one of those practices that's really hard to teach. A big part of the job for a software engineer is balancing abstraction with specificity. The argument from the architecture astronauts is always that once the system gets big, we'll be glad to have the AbstractServiceFactoryFactoryManagerFactory. My argument is that unless we're shipping the "big system" on this release cycle, we should do what's best for the small system. In all likelihood the system will never get big and by the time it does the requirements will change. In all likelihood useful components will get rewritten many times anyway.

I think YAGNI is a really good rule of thumb when you define "need it" as "need it for the current release".

๐Ÿ‘คrgbrgb๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

There are three reasons why YAGNI works so well.

First, people systematically underestimate uncertainty. The human brain is good at recognizing patterns and making plans but not so good at dealing with randomness and uncertainty. When talking about software development and maintenance we're talking timescales of years. Companies go out of business, projects get cancelled, code gets thrown out and rewritten. It's easy to paint a pretty picture about how the Cat class will get added to the Pet hierarchy but there is tons of uncertainty involved in even the simplest project. Because the scenario is specific the brain overvalues its likelihood compared to the nebulous unknown alternatives.

Second, keeping code as simple as possible is almost always for the best. YAGNI forces smaller simpler code. More complexity and more code means more room for bugs. All the studies I know of consistently show that more code means more bugs.

Finally YAGNI is a principle that forces priorities to be in the right place. The question is never between spending time making something that might be useful in the future or doing nothing, it's between doing one particular useful thing or another. I can't think of a single case where the right priority is to do something that MIGHT help in the future. You start by doing things that DO help now, then things that WILL help in the future.

๐Ÿ‘คnwhitehead๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

It is even simpler than this.

There is a non-linear relationship between number of requirements and the complexity of the resulting software. The exact relationship is hard to nail down - I've seen some data suggesting that complexity goes as the cube of the number of requirements - but it is clearly non-linear.

This goes whether or not the requirements are handed down by a product manager, or generated by a developer who mistakenly believes that the future types of requirements are predictable. The impact on the complexity of our software of additional requirements is all out of whack with how many requirements you added.

Here is food for thought for those who are not convinced. Suppose that a developer who wants to abstract things doubles the set of requirements and the relationship is the cubic one that I suspect. Then your task is 8 times as hard. And you don't have working software until it is done.

Suppose that 2/3 of those requirements turn out to be needed eventually and, horror, there is no way to do it without a complete rewrite. Then you expect the full energy now, 4x as much work later, and your total effort eventually is 5x what it takes to produce what you really needed right now, AND you get to enjoy a working partial solution before you're done.

Even a worst case scenario for YAGNI (yet) comes out better than trying to aggressively plan for the unknown future.

๐Ÿ‘คbtilly๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

The problem with YAGNI as a development slogan is that it can be too broadly applied.

I think a better wording might be, "don't increase complexity writing code you may not need". The issue is usually not the presence of additional code. Rather, it's making design decisions based on requirements that may never in fact come to bear.

๐Ÿ‘คLegion๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

I'll join the chorus. If you're not going to need it don't do it but if you will need and you don't do it you're going to pay dearly. "Software Engineering" is about being able to tell the difference vs. just throwing something together.
๐Ÿ‘คYZF๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

No, i wouldn't think so at all. A little foresight and modular design is not _that_ hard. Sure, after you implement the Dog Class you know better what the Pet Class may need, but you can most likely already have 75% of that Pet Class ready beforehand.

If the OPs software design (for a particular subset!) is so complex he can't imagine it in his head: either the design is too complex or the programmer is not very good, imo.

Any why the hell do we need the next acronym?!

๐Ÿ‘คbuster๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

I was nodding along, but man was that example painful. I'm sure that it was in good effort...but it really didn't do justice to why YAGNI is bad.

I'll bite: it's really terrible for security purposes. Aside from the typical YAGNI feature examples, there's plenty for application maintenance and back-end development.

Let's say you have a database with several layers of privileges. You frequently have to perform actions that require higher privileges than that user has, and you're a lazy dev. So you try to automate this process by adding further code to your system design, expediating the entire process at the cost of some authentication.

Bam, huge red flag and a half. Yes, you can have this and defend it at the same time, but in most cases, it's silly to try. Adding code just adds another vector and a half.

That said, yes of course adding features you don't need will bloat the system. But that pet example kinda sucked, I'm sorry.

๐Ÿ‘คdylangs1030๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

Design Patterns are one of the biggest culprits in large, over-engineered patterns. http://37signals.com/svn/posts/3341-pattern-vision
๐Ÿ‘คdrylight๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

Perfect post about one of the most important principles in programming. Nine out of ten, concise design with fewer lines of code is better design than over-engineered abstractions over abstractions over abstractions over...
๐Ÿ‘คapphrase๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

If you are going to use a rule like this, you really need agile project management to guide what you are going to need. If you are doing Scrum properly, you plan the features (and internal architecture needed for those features) for up to a month at a time, but you don't architect for purely internal things more than a month in advance (the YAGNI principle) since one of the Scrum principles is to limit work in progress.

If you are doing a waterfall PM process, it doesn't apply so much.

๐Ÿ‘คA1kmm๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

I totally agree! The problem is that sometimes you just can't convince your coworkers. They'll say this XYZ feature is coming sooner or later, they'll argue that abstraction means cleanness. And as future is so uncertain, arguing about what might happen in the future always ends up with no conclusion, and they still think their future-proof approach is worth it.
๐Ÿ‘คhackernewsguy๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

I'd like to see some analysis on the real "cost" of a line of code.
๐Ÿ‘คbetenoire๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0

(Replying to PARENT post)

This sort of reminds me of Minimum Viable Product methodology (MVP) but I think YAGNI is at a later stage in the development cycle.
๐Ÿ‘คawjr๐Ÿ•‘12y๐Ÿ”ผ0๐Ÿ—จ๏ธ0