Defensive programming is as reasonable as defensive driving.
It may be helpful to think of this in terms of separate concerns. One concern is the presentation. Another may be a set of business rules. It is reasonable to make the same check in both places.
You want to make the check in the presentation layer to communicate to the user.
You may also want to make the check below the presentation layer:
- To defend against present and future mistakes in the presentation layer.
- In case the code underneath the presentation layer is re-used elsewhere.
- [From mvds's comment] In case the condition may change since the control was enabled or disabled.
Edit: David Heffernan's DRY concern below can be addressed trivially by defining the condition exactly once, and accessing it elsewhere.
void setup_gui()
{
some_button.setEnabled( context.isThisActionAvailable() );
...
}
void some_button_click()
{
if ( context.isThisActionAvailable() )
return;
...
}