four ways to implement the singleton pattern