I can only think of two good reasons for having an apply button:
- The changes can't be applied instantly but will lock the GUI for a noticable amount of time.
- The changes only makes sence together (like a transaction).
None of those are very common. Historacally 1 used to be true for almost any option. But nowadays computers are faster and 1 is seldom relevant. If the effect of the changed can be seen instantly, why would anyone not want that? So the gui (but often not the code) can be simplified by skipping the apply step. I don't think it's very common that a user really needs the cancel button either, partly because it's kind of ambiguous. What should I expect if I make one change, apply, make some other change and press cancel? Will the first change be reverted (in most applications the answer is no because that's easier to implement)?
If yes, that is the point of having the apply button then everything is deceded then pressing OK/cancel anyway? Or do we need to consider yet another option, that the window is closed, in which case the first change is kept but the second reverted?
If no, then apply basically sets a bookmark which will be reverted to is cancel is pressed. But is this kind of complex behaviour really needed in any real life use case?
Is it sane to keep this kind of complexity of historical reasons because users (are believed to) expect it? I have seen users always press apply, then OK. Why? Perhaps just because the GUI is too complex. Or becuase the are not sure if "apply" means "apply and dismiss dialog" (which it does in some applications) and that OK might not apply the changes (I have seen buggy applications where OK just closes the window without applying and maybe they have too). At least I don't think users in general are awere of the exact logics of these complex choises, hence they do not need it and it doesn't need to be there. People tend to mainly distinguish between "positive" (yes, ok, go forward, apply) and "negative" (no, cancel, abort, go back) actions is dialogs, having more than one of either requires more attension from the user. Interestingly, exchanging one positiva action with another doesn't seem to affect the users perception much. If a dialog with buttons yes/no is changed to ok/cancel, many users won't even notice.
That about usability (which is far more important IMHO). Maintainability-wise instant apply can be very messy if done wrong, but also very clean and maintainable then done right. If the application is written with an apply-all-at-once approach there is generally one function. Calling such a function for every little change is of course not very efficient. What I have seen this is often solved by splitting the function to several different functions for applying different stuff, ideally one dedicated function for every kind of change that can be made. This is will make the application much more responsive, but is horrible to maintain. So don't go there. A neat solution is to use MVC (Model-View-Controller) and create a model for each configuration item and bind them to the fields in the configuration form as well as to the relevant parts of the application (and to the configuration storage back-end so every change gets saved automatically). If no MVC is available in the environment in question, it is definitely worth writing one.