I have a smart contract which I might want to modify in future. Should I use self-destruct to destruct that contract and then deploy a new one? Or, should I make that contract upgradable to make changes in future? Which one is most feasible solution in terms of cost and other factors?
The cost is theoretically the same. It's really up to your own preference if you want the old contract to continue existing or not.
One benefit to using an upgrade-able contract is that it can store a reference to the new contract which could make it easier for someone to find the newer contract.
One downside to using an upgrade-able contract is that people may continue trying to use the old contract (which you may or may not have disabled functionality for) and that could be quite frustrating as a user.
selfdestruct will remove all storage from the state, which isn't ideal if you might ever need it in future.
Upgradeable contracts can be established with a version flag and a pointer to the address of any new contracts after they are deprecated - you could also include a 'pause' function in your contract (with an
onlyOwner modifier to make sure nobody else pauses it) so once it has been deprecated the functions within the original contract no longer work.
We use a contract register on our private chain to keep an eye on the latest version of each contract - when updates are made the original contract is paused, its
latestVersion bool is set to false and
successorAddress is added to their register mapping entry to point towards the correct new version. Our contract register is also upgradeable, for additional resilience :)
There is plenty of in-depth coverage on this topic in this question