没有了单例模式,我们必须在代码的各个地方传递该实例。这变得非常混乱,所以我们编写了一个单例包装器。现在我们正在将相同的代码移植到 PHP 和 .NET,我想知道是否有更好的模式可用于配置对象。
最后一篇文章详细解释了如何将新对象的创建转移到工厂中,以避免使用单例。值得一读。
简而言之,我们将所有 new 操作符移动到工厂中。 将所有生命周期相似的对象分组到一个工厂中。
最好的方法是使用工厂模式。在创建类的新实例时(在工厂中),您可以将“全局”数据插入到新构造的对象中,可以作为对单个实例的引用(存储在工厂类中)或通过将相关数据复制到新对象中来实现。
然后,您的所有对象都将包含以前存在于单例中的数据。总体上我认为两种方法差别不大,但这样做可以使您的代码更易于理解。
不要将所有责任都积累到单个配置对象中,因为这会导致一个非常庞大且难以理解和脆弱的对象。
例如,如果您需要向特定类添加另一个参数,则更改Configuration
对象,然后重新编译使用它的所有类。这有点棘手。
尝试重构代码以避免使用常见、全局和大型的Configuration
对象。仅向客户端类传递所需的参数:
class Server {
int port;
Server(Configuration config) {
this.port = config.getServerPort();
}
}
应该重构为:
class Server {
public Server(int port) {
this.port = port;
}
}
一个依赖注入框架在这里会很有帮助,但并非必需。
scope="singleton"
),只会创建一个bean实例,并且每次在依赖项中使用该bean或通过getBean()
检索时都会返回该实例。另一种方法是直接传入所需内容,而不是要求对象提供信息。
你可以通过使用静态方法来实现单例的相同行为。Steve Yegge在this帖子中非常好地解释了这一点。
也许不是很干净,但你可以将想要更改的信息位传递给创建单例的方法,而不是使用
public static Singleton getInstance() {
if(singleton != null)
createSingleton();
return singleton;
}
}
您可以在应用程序启动时(以及单元测试的setUp方法中)直接调用createSingleton(Information info)
。
检查将配置作为回调接口的可能性。 这样,您的配置敏感代码将如下所示:
MyReuseCode.Configure(IConfiguration)
系统初始化代码将如下所示:
Library.init(MyIConfigurationImpl)
一个只包含静态方法和字段的类是可能的吗?我不确定你的具体情况是什么,但值得研究一下。