I would use something like the Factory Pattern. It would return the concrete implementation of the persistence method you require.
public class Program
{
public void SaveGame()
{
var gameSaveFormat = ConfigurationManager.AppSettings["gameSaveFormat"];
var persistence = PersistenceFactory.GetSaveMethod(gameSaveFormat);
persistence.SaveGame();
}
}
public interface IPersistence
{
void SaveGame();
}
public abstract class Persistence : IPersistence
{
public abstract void SaveGame();
}
public class SaveToDatabasePersistence : Persistence
{
public override void SaveGame()
{
//Implement SaveToDB
}
}
public class SaveToXmlPersistence : Persistence
{
public override void SaveGame()
{
//Implement SaveToXML File
}
}
public static class PersistenceFactory
{
public static IPersistence GetSaveMethod(string saveMethod)
{
switch (saveMethod)
{
case "Xml":
return new SaveToXmlPersistence();
break;
case "DB":
return new SaveToDatabasePersistence();
break;
default:
throw new Exception(string.Format("Unknown Save Method. {0}", saveMethod));
}
}
}
The GetSaveMethod would accept a string that would define the concrete type that you wish to return.
The Persistence abstract class is optional. You should use it if you require common functionality between concrete implementations. If you choose not to use it, each concrete type should implement the interface directly.
You haven't specified what language you are using, but in .NET you can use the ConfigurationManager class to read the persistence method from a configuration file.
Lastly
I'm hesitant to use a Singleton due to all the bad reviews I read about it, and I don't really want to have to pass this object around to every class just in case I need to save something.
doesn't quite make sense. A Singleton class is called when necessary. An object being passed to every class just in case you need to use it, is certainly an incorrect implementation of that pattern.
public void SaveGame()
{
var persitanceMethod = MySingleton.GetInstance().PersitanceMethod;
var persistence = PersistenceFactory.GetSaveMethod(persitanceMethod);
persistence.SaveGame();
}
The above code would be an example (from my head) of how you would call a singleton class to retrieve a property from it.
Update
public class Program
{
private readonly IPersistence _persistence;
public Program(IPersistence persistence)
{
_persistence = persistence;
}
public void SaveGame()
{
var persistenceObject = PersistenceFactory.GetSaveMethod(_persistence.GameSaveFormat);
persistenceObject.SaveGame();
}