用于创建特定视图元素的设计模式
Design pattern for create specific view elements
假设我们有一个为我们创建一些产品的抽象工厂。我们知道抽象工厂可以为我们提供产品的一些特定的子类,但是我们不想检查类型(这是这种模式的主要原因)。
现在我们需要为每种类型的对象创建一个特定的视图,我们如何在不知道具体类型的情况下做到这一点?
同一个工厂应该创建不同的视图吗?
更新:我创建了一个 github repo 来尝试所有不同的方法。
这个问题可以看看抽象工厂模式在ADO.NET中是如何实现的。
我们有一个名为 DbProviderFactory
的抽象工厂。这个工厂有几个实现,如 SqlClientFactory
、MySqlClientFactory
、OracleClientFactory
等
对于这个问题,产品是数据库相关对象,如连接、命令、数据适配器等。
起初我们的抽象工厂给了我们一个连接(产品)。它可以是 MySqlConnection
或 OracleConnection
。我们唯一知道的是,它是一个 DbConnection
.
DbProviderFactory factory = ...
DbConnection conn = factory.CreateConnection();
现在我们需要创建一个可以与此连接一起使用的命令对象(视图)。
DbCommand cmd = conn.CreateCommand();
如您所见,命令(视图)是由连接(产品)创建的,而不是由抽象工厂创建的。
但这并不完全正确...
实际发生的事情隐藏在实施细节中。当抽象工厂创建连接时,它会将自身传递给连接。当我们请求命令时,连接通过提供的抽象工厂创建命令。
所以,如果我们 return 解决您的问题,实施可以是这样的。
interface IView {
IProduct Product { get; set; }
void Render();
}
interface IProduct {
IView CreateView();
}
interface IAbstractFactory {
IProduct CreateProduct();
IView CreateView();
}
class View1 : IView {
public IProduct Product { get; set; }
public void Render() {
Product1 p1 = (Product1)Product;
// Do product1 specific rendering here
}
}
class Product1 : IProduct {
private IAbstractFactory factory;
public Product1(IAbstractFactory factory) {
this.factory = factory;
}
public IView CreateView() {
IView view = factory.CreateView();
view.Product = this;
return this;
}
}
class Factory1 : IAbstractFactory {
IProduct CreateProduct() {
return new Product1(this);
}
IView CreateView() {
return new View1();
}
}
假设我们有一个为我们创建一些产品的抽象工厂。我们知道抽象工厂可以为我们提供产品的一些特定的子类,但是我们不想检查类型(这是这种模式的主要原因)。 现在我们需要为每种类型的对象创建一个特定的视图,我们如何在不知道具体类型的情况下做到这一点? 同一个工厂应该创建不同的视图吗?
更新:我创建了一个 github repo 来尝试所有不同的方法。
这个问题可以看看抽象工厂模式在ADO.NET中是如何实现的。
我们有一个名为 DbProviderFactory
的抽象工厂。这个工厂有几个实现,如 SqlClientFactory
、MySqlClientFactory
、OracleClientFactory
等
对于这个问题,产品是数据库相关对象,如连接、命令、数据适配器等。
起初我们的抽象工厂给了我们一个连接(产品)。它可以是 MySqlConnection
或 OracleConnection
。我们唯一知道的是,它是一个 DbConnection
.
DbProviderFactory factory = ...
DbConnection conn = factory.CreateConnection();
现在我们需要创建一个可以与此连接一起使用的命令对象(视图)。
DbCommand cmd = conn.CreateCommand();
如您所见,命令(视图)是由连接(产品)创建的,而不是由抽象工厂创建的。
但这并不完全正确...
实际发生的事情隐藏在实施细节中。当抽象工厂创建连接时,它会将自身传递给连接。当我们请求命令时,连接通过提供的抽象工厂创建命令。
所以,如果我们 return 解决您的问题,实施可以是这样的。
interface IView {
IProduct Product { get; set; }
void Render();
}
interface IProduct {
IView CreateView();
}
interface IAbstractFactory {
IProduct CreateProduct();
IView CreateView();
}
class View1 : IView {
public IProduct Product { get; set; }
public void Render() {
Product1 p1 = (Product1)Product;
// Do product1 specific rendering here
}
}
class Product1 : IProduct {
private IAbstractFactory factory;
public Product1(IAbstractFactory factory) {
this.factory = factory;
}
public IView CreateView() {
IView view = factory.CreateView();
view.Product = this;
return this;
}
}
class Factory1 : IAbstractFactory {
IProduct CreateProduct() {
return new Product1(this);
}
IView CreateView() {
return new View1();
}
}