【发布时间】:2013-06-13 10:19:55
【问题描述】:
来自傻瓜的设计模式:
你去 - 你有一个工厂类
我从工厂模式中了解到的是它可以帮助我们避免在需要创建新对象时不断修改代码。但是函数createConnection赢了不必修改它来创建和添加另一个对象?那么这有什么帮助呢?
我错过了什么?
【问题讨论】:
标签: design-patterns factory-pattern
来自傻瓜的设计模式:
你去 - 你有一个工厂类
我从工厂模式中了解到的是它可以帮助我们避免在需要创建新对象时不断修改代码。但是函数createConnection赢了不必修改它来创建和添加另一个对象?那么这有什么帮助呢?
我错过了什么?
【问题讨论】:
标签: design-patterns factory-pattern
工厂模式可用于限制您必须进行的代码更改次数。以您的代码为例,假设您有很多使用数据库连接的函数
void ExampleMethod() {
var con = new MySqlConnection();
// do something with con
}
现在您想使用 Oracle 而不是 MySQL,因此您必须将每行 new MySqlConnection 更改为 new OracleConnection。
工厂可以解决这个问题
void ExampleMethodUsingFactories() {
var con = factoryInstance.createConnection();
}
factoryInstance 被实例化一次,factoryInstance = new FirstFactory("MySql")。现在更改整个程序以使用 Oracle 变得微不足道。您只需将“MySQL”替换为“Oracle”。您不必更改实际使用数据库连接的方法。
当然,添加新的数据库引擎仍然意味着您必须更改工厂代码,但这只是一类。
【讨论】:
这是一个糟糕的设计。不是SOLID。大多数情况下,在运行时比较类型是糟糕设计的标志。多态性就是答案。更糟糕的是,这个工厂只能产生一种连接,所以它应该比较字符串一次,而不是在每次调用 CreateConnection 时都进行比较。是什么让它变得更糟 - 字符串。为什么不枚举或静态整数? (这个例子的所有错误当然是由它的示范性质引起的。但是这种类型的每个例子都应该有一个关于缺陷的旁注 - 因为它可能会粘住 - 当你阅读一本手册时,你自然会假设它所说的是正确)
在这种情况下,正确的工厂是:
public interface ConnectionFactory {
Connection createConnection();
}
public class OracleConnectionFactory implements ConnectionFactory {
public Connection createConnection(){
return new OracleConnection();
}
}
public class SqlServerConnectionFactory implements ConnectionFactory {
public Connection createConnection(){
return new SqlServerConnection();
}
}
安装于:
FirstFactory factory = new FirstFactory("Oracle");
你会:
ConnectionFactory factory = new OracleConnectionFactory();
当您想要一种新的连接类型时,您将添加一个新工厂,并更改这一行,您不必修改现有的类。
【讨论】: