How far do you go with YAGNI? [closed]
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this questionI am developing a new revolutionary web application for the enterprise market. Sure, many before me thought that their web app would be revolutionary only to find out it isn't. (Or it is, but the business is not good anyway).
So I'm am thinking, in order to find out if my idea has any traction with the lowest cost, to follow an extreme YAGNI:
No security features (i.e., no users, etc). For any new customer I install a new database instance and a new webapp instance. Each webapp instance is protected by a http server password (digest or basic authorization, perhaps over https).
No internationalization. Just english string embedded in the source code.
No deco开发者_高级运维upling. Just webpages that talk to the database.
No performance tricks. No queues, caches, timers, background jobs, asynchronous calls, etc.
No scalability. No database partitioning, no shards, no clustering or replication.
Additionally, use YAGNI at the micro level whenever suitable.
I just want to start the project and reach as fast as possible a point where I can sell (or try to sell) my innovative features with a simple and engaging UI.
If the plan fails, I will know early. If it succeeds, I will see what customers want then. Do they want a french version? Or do they want users and roles within the organization?
Is this what people mean by YAGNI, or is this a pathological and exagerated example of YAGNI?
I wholeheartedly agree with the YAGNI principle, but you still want to plan for success. If an application needs a complete rewrite when it suddenly has more than ten users, then it's YAGNI taken too far.
Some things You Are Gonna Need. From my perspective, the two most important points:
Don't shoot yourself in the foot by not preparing your app for internationalization. If your application is any good, internationalization is going to be on the table one day. Also, the ability to handle foreign characters by using UTF-8 is an absolute requirement when building an application from scratch in 2010. Internationalization may seem not that important to an english native speaker, but believe me, it is essential and the pain of internationalizing an application later is horrible.
Think twice about the no security features thing. What about an organization or group that wants to work with your app with users on different security levels. It could be that this is a feature you can really do without - I have a fine-grained security system built into many of my products that has never been used to its full potential yet. But think well about whether your specific application can do without, even if it is successful.
This is what they call "prototyping". Go for it.
There's a subtlety between YAGNI and prototyping.
When it's user-requested featuritis, and you say no, that's YAGNI.
When it's implementation (I18N, "decoupling"(?), queues, caches, timers, etc.) and you say no to yourself. That's not really YAGNI. That's prototyping.
Most of what you have here does not seem to be user-oriented gold-plating. I wouldn't call this -- precisely -- YAGNI.
YAGNI is about reminding you to see the difference between what you can do and what you need to do to satisfy your requirements.
For example,if your requirement says "let people create accounts and log in", just use your framework's default auth methods and move on to the next requirement.
Your web app can support OpenID, Active Directory, Local Database, Flat File, and a zillion other kinds of authentication methods, but you can satisfy the requirement by implementing the simplest one. (To me, YAGNI implies DTSTTCPW).
"I can do anything, given enough time"
- Every Programmer I've Ever Met
Not a fan of the YAGNI principle myself; I see it used far too often in the justification of poorly-designed software. Over-designed software is a problem too of course, but "YAGNI" doesn't really leave much room for actual impact analysis.
It turns out that in the world of software, many of the things that you think you aren't going to need, you actually are going to need. And then some. Who'dathunkit.
I've written one or two apps that were supposed to be throwaway apps or hold-overs that are still in production after two years. They are a pain to maintain.
Especially when it comes to something like security - you probably are going to need it.
YAGNI is a good principle but it is not the only design principle. Many of the above make sense to get a product in front of users quickly. But if, for example, the web pages that talk directly to the database begin to each have duplicated code you are going to find that slavish dependence on one principle (YAGNI) to the exclusion of others (in this case DRY) will limit your ability to respond to your hopefully growing number of users' feature requests.
If you are going to truly develop a revolutionary web application for the enterprise market I'm not really sure which of those things You Aint Gonna Need.
Also your examples are pretty specific. For instance when you say: "no security features"... I'd say that users is one thing you maybe can do without, but sanitizing your inputs is one you can't. Also "scalability" is not a matter of database sharding or replication, those are decisions you take after you realize your application does not scale well.
I'd rather be careful when using YAGNI as a high-level design guideline, It fit's best when you talk about odd product features or maybe software components extreme flexibility.
Just my 0.2
If you take "YAGNI" to that extreme (and I'll sidestep discussions on whether or not that's a good idea as well as discussions on whether or not that's really "YAGNI"), you should be prepared to mercilessly refactor your codebase to add in later what you leave out now without creating a Ball of Mud.
In my mind YAGNI is most commonly used in context with a developer thinking "oh it would be smart if we also added feature X. We might need it in the future." Never ever add features that isn't a requirement.
That being said your code should always be open for modifications if your customer thinks feature Y is absolutely necessary. A good architecture is a must!
Regarding to scalability, queues, caching: it depends. What is the requirement for the application? Is it an intranet site used by 10 concurrent users or is it a popular website with millions of users. It depends. Find the requirements and do that - nothing more. YAGNI. If your requirement change; change your application - it should be open for modifications.
YAGNI is good if there's a decent chance you'll never need it. If you don't need it now but you're almost sure you'll need it in the foreseeable future, then it's almost always easier to fit it in up front than later. When you justify not implementing things that you don't need this second but will almost certainly need in the near future by YAGNI, that's where problems begin.
The point that YAGNI is only one great principal among many is a good one to remember; sometimes YAGNI suggests one decision but there are equally good (or better) reasons to prefer another.
Here's one area where I feel some YAGNI proponents may go to far: if you're comfortable with OOD/polymorphism, it usually costs you very little to "bake in" some great extension points for future use, even in a prototype.
Here's an example...
You're creating a prototype webapp that includes the ability to display a print-friendly version of a report. You need to work quickly, but have a pretty good feeling the steakholders will ask for the ability to email the report as well down the line.
In your server-side Java code, hide the knowledge of the fact that the report is being prepared for the printer behind an interface. Create a concrete class that extends the interface to hold that responsibility. Don't actually go off and write an email version of the interface, because YAGNI. But if you ever do, you're set to add it without carnage to your existing features.
I would say that if you are starting out by throwing away all common sense and doing the whole project in the most expediant way possible, then what you will end up with is a big pile of fail... Which is by no means Revolutionary(tm).
If you truly want to know whether it is going to be useful, do some screen mock ups. Maybe even just regular old hard coded html. Take those to potential clients and see if you can get your foot in the door. If some of them start to bite, then bust your butt and build it.
It's going to take time to get a contract in place, get payment, and get someone on your clients staff to actually start using it. While that's going on, build it.
Most likely what is going to happen is that potential clients will see your app and, hopefully, tell you why it doesn't work for them. Change the mock ups and go back. Iterate as necessary until you have a front end design for your product that someone is willing to pay for.
What I would do is:
1) Design it taking in consideration the right architectural decisions. Internationalization and Security are probably must haves in this case.
2) When developing, create the hooks for those principles to be implemented later. So when you have time and budget, you can implemente them without doing major remodeling.
3) Then you can concentrate on the features that would make your application fly and are more important to your potential clients.
So I think that in this case I would be using more of the KISS approach than "extreme YAGNI" as you suggested.
In my opinion, YAGNI should be followed by default as it allows for boosting productivity greatly.
There are some exceptions, thought. For example, if you develop a 3rd party library, you do need to think at least a little bit ahead of time and anticipate some future users' needs. That is not to say that you have to give up on YAGNI completely, but you shouldn't follow it as strictly as with an in-house development.
Yes, BUT...
I tend to agree with many of your considerations except the "no decoupling", because the "it" in YAGNI stands for functionality, not for thinking steps. Introducing a few abstractions (just those needed for decoupling) will pay off immediately in terms of errors not made or errors more quickly found and removed.
A nice (because it saves you thinking) way to introduce those abstractions would be to use a good web framework and simply follow its suggested application structuring style.
As a fringe benefit, it would then become much easier to add the security, internationalization, performance, and scaling stuff later and your YAGNI-behavior-now should become reasonably safe.
(Unfortunately, the argument applies only if you know the web framework already. Knowledge reigns supreme in YAGNI kingdom.)
精彩评论