Let us imagine we have an object D, containing some data. This is modified differently across two different locations, giving rise to data objects D1 and D2. Depending upon the contents, D1 and D2 may be in conflict with each other when being merged back as part of a synchronization process.
Systems such as version control systems simply point out that the two data objects are in conflict with each other and leave it upon the user to manually resolve the conflict.
However, let us now imagine a consumer-facing application, such as a note-taking application that synchronizes contents online. In this case, no user will want to manually resolve conflicts that may have arisen due to the user typing out two versions of the same note with different contents. Discarding the older object for the newer object isn't possible either, since there may be valuable content in the older object that the user wants.
How should I go about resolving such conflicts in a consumer-facing application?
Well, if you don't want manual conflict resolution, then you will have to automatically merge changes from both updates.
There is no way that works well for all applications. When you have a requirement like this, you have to carefully design the application so that automatic merging makes sense.
There are a few common approaches, and you can do one or all of them in various combinations:
1) Merge updates really fast. Think google docs -- updates are merged in real time as people edit. Operational Transformation (https://en.wikipedia.org/wiki/Operational_transformation) is a good way to understand exactly how to do that kind of merging, but it doesn't have to be as complicated as that doc. The reason this works well is that updates are small and you can tell if someone is messing with your stuff before you put a lot of work into it. Politeness fixes conflicts -- one of you will wait until the other is done with that stuff.
2) Locking. If you click the edit button on a note, make lock it so that nobody else can edit it until you're done, etc. This is old-school, and not nearly as slick as (1), but it can work in situations where you can't merge fast enough to do (1).
3) Design your data model and interface to make merged versions as nice as possible. If anyone can add notes, but a note can only be edited by its owner, then no problem, for example. Or maybe you can only edit my stuff if you ask permission first and I give it to you. As things get more complicated than that, this becomes increasingly difficult. It's not usually possible to do this well if you're not willing to make sacrifices in application functionality. You've got one thing on your side, though: It's rude to mess with someone else's work, so a lot of the things you can do look like you did them just to enforce good behavior, and users will thank you for them if you did it with finesse.
Related
This is an interesting interview question that I found somewhere. To elaborate more:
You are expected to design classes and data structures for some website such as facebook or linkedin where your activity can be shared and re-shared. Design should be such that it avoids redundancy and duplication.
While thinking of this problem I was stuck on "link vs copy" problem as discussed here
But since the problem states that duplication should be avoided I decided to go "link" way. This makes sharing/re-sharing easier but deleting very difficult. i.e. if the original user deletes their post all the shares should be deleted. (programmatically speaking all the objects on the pointing to the particular activity should be made null. And this is the difficult part here, i.e. to find all the pointing objects)
Wouldn't it be better to keep the shares? The original user deletes
their post, fine, it's gone. But everyone who has linked to it should
not suddenly have it disappear on them.
This could be done the way Unix handles hard links. "Deleting" just
means removing one link to an object -- an inode, in Unix terms. You
don't remove the object itself until the link count is zero.
It's not obvious from the original specification that deletion should work as you describe. It might be desired that when the original user deletes the item, it is not deleted elsewhere; in that case you don't necessarily need to track all references, just keep a reference count on each post, and remove it from the database only when the count hits zero.
If you do want the behavior you describe, it may be achievable by simply removing broken links as and when you encounter them, again relieving you of the need to track each reference. The cost of tracking and updating every reference to every post is replaced with the comparable cost of one failed lookup for each referring page. The latter case is simpler to implement, though, and the cost doesn't hit your server all at once.
In real life, I would implement all references as bidirectional anyway, because it's likely to be needed sooner or later as you add features. For example, a "like" counter seems pretty simple, but to prevent duplicate votes you need to keep track of who has liked each item, and then if you want to remove their "like" when they delete their profile, you need to keep a list of each user's outbound "likes" too.
It takes a lot of database activity to implement something like Facebook...
I was thinking that I’d rather only use the Task Work Item and ignore the Bug Work Item. This is my thinking as I set things up for my team. I’m on a quest to see why I shouldn’t do this. From my perspective a Task is either a new item or a bug item. There is no need to use two distinct Work Item Types. To make this happen in TFS I’ll start with the Bug Work Item and create a custom field (“Item Type”) to distinguish the two task types: new/bug. Both new tasks and bugs will share the same fields. Anyone see any major drawbacks to this approach?
The main reason Tasks/Issue/Bugs/etc are different work items are because the individual fields of each work type can be configured differently.
For example, by default, Bugs have a Triage property, Issues have Due date, Tasks have a Discipline. The States of a Bug (Active/Closed/Resolve) are different from an issue (Active/Closed).
By merging them into a single work item type you would loose the ability to configure each one uniquely.
Also, the rules followed when a Bug and Task are closed, for example, are generally different. Segregating them into work items allows a simpler rules set.
Work item type is also a standard column in all queries.
Overall, it depends on how extensively you are using Team Foundation. If your project is small, and the above don't matter, it's not going to hurt. Though I don't see much gain either.
I would suggest keeping Bug and dropping Task if you want to merge them. By default when you check in code and Resolve with a bug, it sets the status to Resolved and assigns it to whoever created it - usually a tester, but in your case possibly a PM. That person can then test to confirm the work is done and close it. You can set up alerts on their work items so they get an email and know that progress has happened. Alternatively if you use Task, when you Resolve at check in it is just closed. No alerts, no further testing. YMMV but on some of our projects we use Bug for things like "user would like to add a new report" and it fits our process well. (For others we keep the distinction for reporting purposes.)
It all boils down to 3 things:
Creation / prioritization
Reporting / Notifications
Completion workflow
Typically creation of a Task involves different fields than a Bug. For a bug you'll want to know things like environment found in, who notified you, severity, priority, etc.
For tasks you usually want to know the requestor, reason behind it, business unit impacted and iteration it is scheduled for. Tasks might be long term goals that result in new or enhanced functionality.
Reporting and Notifications of the two are generally different as well. PM's are going to track tasks to ensure deliverables are met, your tech support area is going to track bugs.
Next, bugs will generally result in hotfixes and service packs. Depending on severity this this might involve a high priority push through QA and release as quickly as possible. Tasks are more laid back and will go through all forms of regression and regular testing with a period of acceptance by the impacted business unit.
Finally, bugs may impact previous versions of your software. Tasks will almost always be for either the version currently under development or the one after that.
In short, they are fundamentally different things. They might share most fields in common, however by combining them you are restricting yourself in both reporting and workflows. Today this might be okay; however within the next month or next year this could seriously restrict you.
Considering that maintainence of work item types is an incredibly easy thing there is almost no benefit to merging them.
My boss believes that wizards make things simple for the user.
I think they have their place but I can't really define what that place is.
I feel there is a danger in turning something into steps that doesn't need them.
Does anyone know where I could find rules for such things, or even a guideline to follow that describes when and when not to use wizards and possibly even other UI elements.
Here is what some common Human Interface Guidelines have to say about when to use them. Most are quite restrictive:
Gnome HIG
An assistant is a secondary window that guides the user through an operation by breaking it into sequential steps. Assistants are useful for making complex operations less intimidating, as they restrict the information visible to the user at any given moment.
[...]
Assistants do have major downsides. After using an assistant it is often hard to figure out where the individual settings aggregated into the assistant are stored. Often people will resort to re-running the assistant, re-entering many settings that they don't want to change.
Assistants are often used in situations where a better solution would be to simplify, or even better automate, the process. Before using an assistant to step people through a complex operation, consider if the operation can be fundamentally simplified so an assistant is unnecessary.
Microsoft Windows Experience Interaction Guidelines:
Consider lightweight alternatives first, such as dialog boxes, task panes, or single pages. Wizards are a heavy UI, best used for multi-step, infrequently performed task. You don't have to use wizards—you can provide helpful information and assistance in any UI.
Apple Human Interface Guidelines
For products with complex setup procedures, a setup assistant can be helpful
(Assistants are not mentioned in any other context, as in the other HIG:s, so I assume that means that Apple think they have no place except for setup)
I'd agree with you that Wizards have their place. And that place is back in Azeroth.
No, but seriously, if the user has to input a lot of different data fields, using a Wizard to split up the data entry into several related groups might help to make things less confusing.
If the Wizard covers a process that consists of steps A, B, and C, and the input at B or C depends on the input at the previous step(s), a Wizard would probably be a good way to structure your application.
There are probably a lot of other situations in which using a Wizard would be warranted (those are just two off the top of my head), but in each case, you'd want to evaluate it and make sure that a Wizard is the absolute best option. To borrow an old saying, everything doesn't become a nail just because your boss wants you to use Wizards as a hammer. If that makes sense.
As far as best practices guidelines goes -- the use of Wizards seems to fall under UX rather than UI, but here's a few items that I came across:
Wizard-style forms best practices
Designing Effective Wizards: A Multidisciplinary Approach (Book)
Best Practice: Designing Wizards
Try reading this.
I would suggest to avoid wizards as much as possible. People have a short attention span and you risk that, at the middle of it, they start forgetting what the said, what they are doing there, etc.
That being said, i think that it may be viable when performing some shopping (e.g., checkout), first-time configurations, others?
When to Develop a Wizard
Always try to:
Only ask the information really needed
Simplify as much as you can, thus avoiding the need to additional explanation
When creating a wizard:
Clearly show the how many steps are needed and how many are completed
Allow the user to revert or cancel it
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
What UI/GUI guidelines should be followed that subtly (or not so subtly) direct users so they don't shoot themselves in the foot.
For instance, you might want to give power users the ability to "clean" a database of infrequently used records, but you don't want a new user to try out that option if they've just spent hours entering new records - they may lose them all because they're 'infrequently used'. Please don't address this specific issue - it's just here to clarify the question.
While one could code a bunch of business logic in place to prevent some issues, you can't account for everything a user might do.
What are some common techniques, tips, and tricks that prevent improper usage?
ie, How should I design the interface to alert users that a function or action is to be taken with care
What should I design in that limits risk and exposure if a poor action is taken?
-Adam
Everything can be undone. Don't erase - deactivate. Back up before every destructive operation, and give the user a way to restore.
That's the path. It's hard to follow it all the way, but it's what you're aiming for.
Make it possible to undo dangerous actions.
If it's a reasonably big application or system, require separate admin access for dangerous operations as well.
Don't Make Me Think
And you can, in fact you HAVE to account for everything they might do. Because you (as the designer) as the one who gives them the ability to do all those things.
Before putting ANY item on a gui as yourself "Can this be misused?" and if it can, you might want to go with a lower level of customizability.
Example hierarchy
Button - Can be clicked.
T/F Radio Button (mandatory) - Only two options.
Combo Box - Many options, possibly "no option". more confusing.
Text field - Myriad of wildly inconsistent options. More confusing for user, more dangerous for coder.
Basically, if the user doesn't need extra options, then don't give them extra options. You'll only confuse them.
This is an old article, but it's still a great one:
Microsoft Inductive User Interface Guidelines
Never rely on anything that says "Are you sure?" The user is ALWAYS sure and that's if they even bothered to read it before dismissing.
Partition your users and have fine-grained permissions.
Define some power-user permissions that enable the "more dangerous" operations.
Power user permission is not given out lightly -- only to actual power users -- and revoked readily.
I'm of the school of thought that, in case of inclarities or ambiguousity, the user is rarely wrong, and the UI is always to blame. So, when you say "punch the user in the face", tagged with "pebkac", I'm thinking that you would do good with a slap in the face.
Unfortunately, I'm unable to give any good UX-advice, since I'm a mere programmer, and therefore more or less by definition disqualify as a good UI-designer. I'd like just to point out the possibility, that you actually could be the one who needs to get a clue, and try to be more humble towards the users.
Edit for Adam:
The little I know about UX is how little I know about it. It's an entire career path. I know for a fact that there's very little anyone can learn by asking a single make-me-good-at-this question at Stack Overflow. It's like me asking "help me write better code", with the body text formulated as a story of how my colleagues ridicule me of my code.
We, programmers, are engineers. We like order and reason and logical decisions. But the average user is not a programmer, not an engineer and, in many cases, not interested in computers themselves the very least bit.
I'm glad that people are giving you nuggets of good advice, and I'm glad that you, contrary to my first impression (I'm sorry about that), are eager to take those bits and understand the needs of the user.
But the point remains: You need to buy books (Don't Make Me Think is a great place to start, as already recommended). You need to watch how people use your software. You need to observe where they stumble, and jig things around until your UIs seem natural.
I'm sorry I still can't give you an answer. Because I don't have it. And even if I would have it, I would probably have to charge you 50EUR an hour, for years into the future.
Make the results of the user's action visible and offer a way to undo those changes.
When the changes are visible, then the user gets feedback of whether the results were what he intended to do, and if they are not, then the possibility to undo will let the user to try again to reach his goal. If possible, make the results of the action visible before the user invokes the action (for example, when dragging some element, show what would happen if the user would release the mouse button, for example visualize addition of the element where it will be moved to and visualize the removal of the element from where it was moved from).
There are a couple of types of undo. The most simple is a single-step undo (as in Notepad), but it is often not enough. Better is a multi-step undo (as in Word), which covers most of the cases, but does not allow undoing a specific action without undoing all the actions that have been done after it. That can be solved by object-specific undo, for example in a form with many fields (or cells in a grid like in Excel), right-clicking the field would show a list of previous values in that field. For deleted data you could have a store of deleted data, from where the user can restore things after deleting them (for example if the user deletes a slide in Powerpoint). And finally you could have a full version history of every change, for example as Local History works in IntelliJ IDEA - make a history entry every time the file is saved (and save everything automatically after a couple seconds of inactivity).
Confirmation dialogs don't help. The user might read it the first time, but soon after that clicking "OK" in the dialog becomes an automated process, and the user will press Enter before the dialog even shows up. Then the confirmation dialog has become just a source of unnecessary mechanical work. The user is always sure about doing some action, even when he is wrong - otherwise he would not have done that action.
Well there are a few different ways that I can/do go about these types of things.
User documentation - first and foremost give them some documentation to work with, and make the systems easy for them to use. Just general usability and descriptive names/actions for everything.
Provide confirmation screens with warnings. Full disclosure of what the action is going to do, with the warnings inside of a yellow box. It draws attention to it and helps prevent the need for the other items.
Have a roll-back plan. For large risky operations you can either simply set "deleted" flags, or offload the data to a temporary "recycle bin" of sorts should they accidentally remove/modify data that was unintended.
Require multiple approvals, for data purge operations especially go to a two-tiered approach, requiring approval from separate users.
These are just a few of the ideas that I have.
Two things immediately come to mind.
The first is the notion of progressive disclosure, i.e., only show users what they need in order to accomplish the task at hand. How many UIs have we seen that have hundreds of controls on a single dialog? Divide the controls into their respective tasks and only allow the user to do a single task at a time. An Advanced button on a dialog is one way to implement this, and this concept has the added benefit of separating the power users from the run-of-the-mill users. Run-of-the-mill users are less likely to attempt a task that is likely to be beyond their skill level.
The second is to leverage the wizard concept for complicated tasks. I know wizards have fallen out of style, but if a task is truly complicated, users usually appreciate having their hands held the first few times. A good example of this is the WinZip wizard interface. If you've never zipped a file before, this wizard uses a logical progression to walk you through the process. And then, once you've grown comfortable with it, you can switch to the classic interface to zip files more quickly.
Of course to do all of this requires a committment not only by the developers, but by management. And that, sadly, is where many of these usability battles are lost.
I've read a statement somewhere that generating UI automatically from DB layout (or business objects, or whatever other business layer) is a bad idea. I can also imagine a few good challenges that one would have to face in order to make something like this.
However I have not seen (nor could find) any examples of people attempting it. Thus I'm wondering - is it really that bad? It's definately not easy, but can it be done with any measure success? What are the major obstacles? It would be great to see some examples of successes and failures.
To clarify - with "generating UI automatically" I mean that the all forms with all their controls are generated completely automatically (at runtime or compile time), based perhaps on some hints in metadata on how the data should be represented. This is in contrast to designing forms by hand (as most people do).
Added: Found this somewhat related question
Added 2: OK, it seems that one way this can get pretty fair results is if enough presentation-related metadata is available. For this approach, how much would be "enough", and would it be any less work than designing the form manually? Does it also provide greater flexibility for future changes?
We had a project which would generate the database tables/stored proc as well as the UI from business classes. It was done in .NET and we used a lot of Custom Attributes on the classes and properties to make it behave how we wanted it to. It worked great though and if you manage to follow your design you can create customizations of your software really easily. We also did have a way of putting in "custom" user controls for some very exceptional cases.
All in all it worked out well for us. Unfortunately it is a sold banking product and there is no available source.
it's ok for something tiny where all you need is a utilitarian method to get the data in.
for anything resembling a real application though, it's a terrible idea. what makes for a good UI is the humanisation factor, the bits you tweak to ensure that this machine reacts well to a person's touch.
you just can't get that when your interface is generated mechanically.... well maybe with something approaching AI. :)
edit - to clarify: UI generated from code/db is fine as a starting point, it's just a rubbish end point.
hey this is not difficult to achieve at all and its not a bad idea at all. it all depends on your project needs. a lot of software products (mind you not projects but products) depend upon this model - so they dont have to rewrite their code / ui logic for different client needs. clients can customize their ui the way they want to using a designer form in the admin system
i have used xml for preserving meta data for this sort of stuff. some of the attributes which i saved for every field were:
friendlyname (label caption)
haspredefinedvalues (yes for drop
down list / multi check box list)
multiselect (if yes then check box
list, if no then drop down list)
datatype
maxlength
required
minvalue
maxvalue
regularexpression
enabled (to show or not to show)
sortkey (order on the web form)
regarding positioning - i did not care much and simply generate table tr td tags 1 below the other - however if you want to implement this as well, you can have 1 more attribute called CssClass where you can define ui specific properties (look and feel, positioning, etc) here
UPDATE: also note a lot of ecommerce products follow this kind of dynamic ui when you want to enter product information - as their clients can be selling everything under the sun from furniture to sex toys ;-) so instead of rewriting their code for every different industry they simply let their clients enter meta data for product attributes via an admin form :-)
i would also recommend you to look at Entity-attribute-value model - it has its own pros and cons but i feel it can be used quite well with your requirements.
In my Opinion there some things you should think about:
Does the customer need a function to customize his UI?
Are there a lot of different attributes or elements?
Is the effort of creating such an "rendering engine" worth it?
Okay, i think that its pretty obvious why you should think about these. It really depends on your project if that kind of model makes sense...
If you want to create some a lot of forms that can be customized at runtime then this model could be pretty uselful. Also, if you need to do a lot of smaller tools and you use this as some kind of "engine" then this effort could be worth it because you can save a lot of time.
With that kind of "rendering engine" you could automatically add error reportings, check the values or add other things that are always build up with the same pattern. But if you have too many of this things, elements or attributes then the performance can go down rapidly.
Another things that becomes interesting in bigger projects is, that changes that have to occur in each form just have to be made in the engine, not in each form. This could save A LOT of time if there is a bug in the finished application.
In our company we use a similar model for an interface generator between cash-software (right now i cant remember the right word for it...) and our application, just that it doesnt create an UI, but an output file for one of the applications.
We use XML to define the structure and how the values need to be converted and so on..
I would say that in most cases the data is not suitable for UI generation. That's why you almost always put a a layer of logic in between to interpret the DB information to the user. Another thing is that when you generate the UI from DB you will end up displaying the inner workings of the system, something that you normally don't want to do.
But it depends on where the DB came from. If it was created to exactly reflect what the users goals of the system is. If the users mental model of what the application should help them with is stored in the DB. Then it might just work. But then you have to start at the users end. If not I suggest you don't go that way.
Can you look on your problem from application architecture perspective? I see you as another database terrorist – trying to solve all by writing stored procedures. Why having UI at all? Try do it in DB script. In effect of such approach – on what composite system you will end up? When system serves different businesses – try modularization, selectively discovered components, restrict sharing references. UI shall be replaceable, independent from business layer. When storing so much data in DB – there is hard dependency of UI – system becomes monolith. How you implement MVVM pattern in scenario when UI is generated? Designers like Blend are containing lots of features, which cannot be replaced by most futuristic UI generator – unless – your development platform is Notepad only.
There is a hybrid approach where forms and all are described in a database to ensure consistency server side, which is then compiled to ensure efficiency client side on deploy.
A real-life example is the enterprise software MS Dynamics AX.
It has a 'Data' database and a 'Model' database.
The 'Model' stores forms, classes, jobs and every artefact the application needs to run.
Deploying the new software structure used to be to dump the model database and initiate a CIL compile (CIL for common intermediate language, something used by Microsoft in .net)
This way is suitable for enterprise-wide software and can handle large customizations. But keep in mind that this approach sets a framework that should be well understood by whoever gonna maintain and customize the application later.
I did this (in PHP / MySQL) to automatically generate sections of a CMS that I was building for a client. It worked OK my main problem was that the code that generates the forms became very opaque and difficult to understand therefore difficult to reuse and modify so I did not reuse it.
Note that the tables followed strict conventions such as naming, etc. which made it possible for the UI to expect particular columns and infer information about the naming of the columns and tables. There is a need for meta information to help the UI display the data.
Generally it can work however the thing is if your UI just mirrors the database then maybe there is lots of room to improve. A good UI should do much more than mirror a database, it should be built around human interaction patterns and preferences, not around the database structure.
So basically if you want to be cheap and do a quick-and-dirty interface which mirrors your DB then go for it. The main challenge would be to find good quality code that can do this or write it yourself.
From my perspective, it was always a problem to change edit forms when a very simple change was needed in a table structure.
I always had the feeling we have to spend too much time on rewriting the CRUD forms instead of developing the useful stuff, like processing / reporting / analyzing data, giving alerts for decisions etc...
For this reason, I made long time ago a code generator. So, it become easier to re-generate the forms with a simple restriction: to keep the CSS classes names. Simply like this!
UI was always based on a very "standard" code, controlled by a custom CSS.
Whenever I needed to change database structure, so update an edit form, I had to re-generate the code and redeploy.
One disadvantage I noticed was about the changes (customizations, improvements etc.) done on the previous generated code, which are lost when you re-generate it.
But anyway, the advantage of having a lot of work done by the code-generator was great!
I initially did it for the 2000s Microsoft ASP (Active Server Pages) & Microsoft SQL Server... so, when that technology was replaced by .NET, my code-generator become obsoleted.
I made something similar for PHP but I never finished it...
Anyway, from small experiments I found that generating code ON THE FLY can be way more helpful (and this approach does not exclude the SAVED generated code): no worries about changing database etc.
So, the next step was to create something that I am very proud to show here, and I think it is one nice resolution for the issue raised in this thread.
I would start with applicable use cases: https://data-seed.tech/usecases.php.
I worked to add details on how to use, but if something is still missing please let me know here!
You can change database structure, and with no line of code you can start edit data, and more like this, you have available an API for CRUD operations.
I am still a fan of the "code-generator" approach, and I think it is just a flavor of using XML/XSLT that I used for DATA-SEED. I plan to add code-generator functionalities.