I always use the software method. Polling the pins in a loop or using a Timer interrupt. The timer interrupt will also provide the debouncing delay.

The main advantage of a timer interrupt is that you need ONLY 1 routine, running in background and you button states are available everywhere, when you need.

That's What Ernie suggested too