This article needs additional citations for verification. (June 2011)
At its core, the anti-pattern consists of a system partitioned into two parts: user interface and business logic, that are coupled through a single point, clicking the "magic pushbutton" or submitting a form of data. As it is a single point interface, this interface becomes over-complicated to implement. The temporal coupling of these units is a major problem: every interaction in the user interface must happen before the pushbutton is pressed, business logic can only be applied after the button was pressed. Cohesion of each unit also tends to be poor: features are bundled together whether they warrant this or not, simply because there is no other structured place in which to put them.
To a user, a magic pushbutton system appears clumsy and frustrating to use. Business logic is unavailable before the button press, so the user interface appears as a bland form-filling exercise. There is no opportunity for assistance in filling out fields, or for offering drop-down lists of acceptable values. In particular, it is impossible to provide assistance with later fields, based on entries already placed in earlier fields. For instance, a choice from a very large list of insurance claim codes might be filtered to a much smaller list, if the user has already selected Home/Car/Pet insurance, or if they have already entered their own identification and so the system can determine the set of risks for which they're actually covered, omitting the obscure policies that are now known to be irrelevant for this transaction.
One of the most off-putting aspects of a magic pushbutton is its tendency for the user interaction to proceed by entering a large volume of data, then having it rejected for some unexpected reason. This is particularly poor design when it is combined with the infamous "Redo from scratch" messages of older systems. Even where a form is returned with the entered data preserved and the problem field highlighted, it is still off-putting to users to have to return to a field that they thought they had completed some minutes earlier.
These features, and their lack with a magic pushbutton, are particularly important for naive users who are likely to make mistakes, less so for experts or the system's own programmers. This type of interface failing has been highlighted by the web, and the need to support more public users, rather than a more traditional user group of role-based office workers, carrying out the same tasks on the same system, over and over. Even though a developer who knows the system intimately and can enter data perfectly the first time around is able to use it efficiently, this is no indication that such a system is suitable for use by its actual users.
The magic pushbutton often arises through poor management of the design process in the early stages, together with a lack of importance placed on user experience, relative to project completion. At a simple view, the simplicity of the magic pushbutton is attractive as it has few user interface modules and their interactions appear simple too. This view hides the complexity inside each module, and also devalues interface quality relative to cost.
In a modern system (i.e., one where processing is cheap and competing interface standards are high), users should simply not be left to enter data for long periods without some automatic interaction to guide, validate, or to tailor the system according to the developing state of the data they've so far entered. Leaving them alone to "just get on with it", then validating everything at the end, means that the corrections needed will be detected further and further from when that data was entered. As an a priori principle, corrections needed should be highlighted as soon and as close to when they are either entered, or could first be identified.
In an event-driven interface, most events triggered by the "completion" of a field will present an opportunity to either validate that field, or to guide the choices for entering the next. They may even control which field the user is taken to next: sub-sections of a form are often made relevant or irrelevant by values entered early on, and users should not need to manually skip these, if it can be done for them.
The following is a typical example of a magic pushbutton in Borland Delphi:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; try reg.RootKey := HKey_Current_User; if reg.OpenKey('\Software\MyCompany', true) then begin reg.WriteString('Filename', Edit1.Text); end; finally reg.Free; end; end;
type TPreferences = class private FFilename: String; procedure SetFilename(const Value: String); public property Filename: String read FFilename write SetFilename; procedure Load; procedure Save; end;
and call this class Save method from the Click handler:
procedure TForm1.Button1Click(Sender: TObject); begin Preferences.Save; end; procedure TForm1.Edit1Change(Sender: TObject); begin Preferences.Filename := Edit1.Text; end;