This guide describes what steps usually work best when adding new features to a product. The guidelines are not mandatory; simpler features may not need any of these steps. They exist to help battle the hardest new features to add :)
The steps are not necessarily in the correct order - this is the usual order. Going back to an older step to add/change things is okay.
Goal: collect all that we can come up with for the new feature or change. Everything goes into an unorganized document (wiki page). Possible ways to organize this document is into proposal items (and proposal detail item for each proposal item).
End product: a brainstorming document with a mess in it.
The design document can contain:
- user scenarios - what should the user be able to do
- presentation/integration/UI - how should the user be able to do it
- dependencies - (additional features only, not new project) - what needs to be done in the rest of the project in order to make the new feature work
- visuals - how the UI should look like (exactly)
- architecture - how the product or feature should be implemented
- data model - data structures (classes)
- modules - what parts should there be in the product. The goal is to make module interaction minimal
- dependencies - (additional features only, not new projects)
- testing - how the product or feature should be tested.
From the collected data, extract a list of things the user will be able to do. Add as much detail as needed.
Here is an example about a "Groups" feature:
- user can create a new group.
- admin can modify the following information about a group: name, picture (optional), activities (optional), country (optional)
- admin must be able to make an event invite (accept) only or all-may-join.
- admin must be able to send invites to users.
- admin can attach various items to the group (events, tracks, photos) and invite users to the group.
- admin can customize the group's page (by picking the current photos, changing the current text, setting the upcoming event)
- user can request to join a group
User scenarios are generally enough to write classic specs. You can extend them beyond a single sentence if you want to be more clear, but keep it to user scenarios (just what can be done, not how or where). If you want you can use the following scheme to add links to terms that need definitions by marking them with
(given that the original document is called documentname). Then, put a header inside documentname-definition with the text "term" and the hash link should work.
For the user scenarios, add details about how to present the information to the user, how to enable the user to do the scenario, and how will the scenario integrate into the existing scheme of the website/app. Describe any specific user interface elements ''if'' they are important. Visual presentation of the design is not 100% necessary but is sometimes desirable.
Here is an example (which is too detailed):
- user can create an event from an event box.
- An event box is available in the main Community page from the create-and-share button menu (integration specification).
- The event box will contain a text box about the name of the event. It will also enable the user to choose between picking a track for the event and setting a single event location on a map. The box will have a start and end date+time pickers. The box will enable the user to add workout types (activities) for the event. The user will pick between private/public event, and a button "add people" will add people to invite in the box. (functionality and presentation specification)
For each scenario, see if there are dependent features. If the dependent feature is not yet implemented or needs to be changed, mark the dependency and if something will need to change, add a note about it. If the feature is not yet implemented or needs to be changed, mark the scenario as currently impossible.
Example: adding an Event object to a Group is impossible if Events are not yet implemented.
- Global overview - not mandatory.
- Data Models -
- Think about the classes you will need to represent data (e.g. Group, GroupMember, GroupInvitee, Event, etc).
- Think about all the attributes they will have (e.g. GroupMember -> Group, User, DateJoined etc).
- Think about how you're going to store them, e.g. Relational (use database relation features) or XML/JSON objects (do not use database relation features) ? Use objects only if you're sure you're not going to do joins or queries inside them but always take them whole.
- Architectural dependencies - Think about what changes there must or should be in existing classes to support the new ones. e.g. hiding GroupMembers for Groups requires that Groups have a new AccessLevel item (MemberVisibility).
- Interfaces - Think about useful interfaces which could represent common functionality in classes. For example, Events and Links have a common interface, CommunityItem, which enables them to be shown on a news feed community page by giving a title-text, an icon image, the creator, description text, and a list of possible community actions.
- View Models - A ViewModel is different in that it does not store any data, only shows existing data in a different way, (e.g. an EventsMap). To design ViewModels you need to do "Presentation" first. ViewModels also include communication API/serialization (JSON models etc.)
- Think about the models needed to represent the pages.
UI prototyping for the presentation (implementing the feature directly) or sketches / vector art (slower). Draw design elements. Try to re-use standard design elements and style as much as possible. Visuals can also be included in the design document...
While prototyping the UI, you may have to update the data model. That is normal as you will always come up with new things to show and remember when you're sketching out functionality.
After you're done with the visual elements, separate and isolate the ViewModels and Controllers. ViewModels are data sets displayed at particular points on the page, while Controllers are the interactions available on that page.
For example, a sidebar containing a file list needs a ViewModel called DirectoryContent, which is an object containing all the necessary information needed to display that partial view. Similarly, it may have a Controller called DirectoryBrowser which allows you to navigate from the current directory to a different directory. In short, a ViewModel contains all the data necessary to display a particular part of the page, while a controller contains all the functions defining the interactions with that part of the page.
Both of these are unavoidably linked together and in modern apps are simply called ViewModels.
ViewModels can be nested. For example, list of files can be a single ViewModel. However it may have a date filter (which allows you to see files modified in the specific range), which is a smaller ViewModel. Generic ViewModels which are reusable on many different pages for many different purposes are called Components. Therefore, a date filter represents a component.
As you implement ViewModels you will have to test them
- Tests for isolated modules and functionality - unit testing
- Tests for critical user scenarios and various cases.
- Make an automated test for every bug encountered twice, and for critical ones encountered once.
- You can go beyond this (stricter rules, test coverage tools), but this is the minimum.