繁体   English   中英

具有数据库使用的设计模式

[英]Design Patterns with database usage

我看到99%的设计模式示例(策略,工厂,装饰器等)具有硬编码信息,每个产品在不同的类中等等。但是,在大多数现实应用中,主要是数据库使用,我们知道为每个产品创建一个类,或使用硬编码信息是不切实际的。

我知道它们都是例子,但我认为从一本书中学到以后这很痛苦:

为店铺NYStore,ChicagoStore创建CheesePizza,VeggiePizza ...和类的课程

对于工厂模式..而在现实生活中,所有这些比萨饼和商店只是数据库中的行。

那么,在这种情况下,使用数据库和设计模式的最佳方法是什么?

  1. 如果比萨饼和商店在数据库中,则不需要使用设计模式。
  2. 使用设计模式,但是每个Pizza或Store创建一个类,只需创建一个从数据库读取数据的类实现(例如DatabasePizza和DatabaseStore!)。

我理解设计模式与支付业务的重要性,例如。 (现金,信用卡,比特币..)每种支付类型都有独特的专业化,而且业务不完全在数据库中(信用卡需要打印收据,比特币需要访问网络服务等)。

但我正在质疑的是:在真正的比萨餐厅,价格,配料,配料,所有根据不同的地方(芝加哥,纽约..)都位于数据库中,设计模式的使用是否真的有必要? 当许多企业位于数据库时,设计模式的使用自然会减少?

......而在现实生活中,所有这些比萨饼和商店都只是数据库中的行。

数据库是否检查您的类提供的不变量,业务规范或一些其他自定义规则(在oop术语中)? 数据库只是大多数应用程序的存储。

这些行是您的域模型和业务逻辑中智能可靠计算的结果。
设计模式可以帮助您构建可以涵盖所有这些业务规则的灵活代码。

我们知道为每个产品创建一个类是不切实际的

设计模式仅仅为行为专业化带来了一些抽象,而不关心数据的严格
实际上,如果创建了ChicagoPizza类,那就是指定一些独特的专业化 ,而不是简单地标记:“这个披萨是芝加哥的”。

我不知道有很多应用程序处理与同一主题相关的数十个对象,它们都具有一些强大而独特的特性

在创建模式的情况下(正如你所提到的),我会说,如果你有这么多只有“性质”不同的“对象”,你应该最终得到一种简单的type属性(在基类上) )在这种情况下映射到数据库而不是使用额外的子类。

我在编程书籍和软件现实之间没有找到任何差距。

您的域模型(按定义硬编码)几乎总是比数据库思维更受青睐。

结论:

我知道他们都是榜样,但我认为从一本书中学到东西后,这很痛苦

如果“例子”意味着与现实不同,那么它们根本就不是例子。
它们只是可以制作的真实软件的一小部分。

我认为你的设计模式示例有点过于字面意思。 显然,CheesePizza和VeggiePizza的例子并不是说每当你有一个处理Pizzas的软件应用程序时,你就必须使用特定的设计模式。 设计模式建议您如何通过打破不必要的依赖关系来设计系统架构以获得更好的可伸缩性和可维护性,然后由您决定哪种设计模式最适合您的应用程序。

工厂模式与数据库没有直接关系,它只是以与Facade模式类似的方式指定工厂对象,其中不需要实例化对象,并且通常/理想消耗代码永远不会知道它正在使用的具体对象是什么,因为工厂对象将服务于接口,基类或抽象类。

无论您选择哪种设计模式,您的系统都应始终与数据库无关,设计模式将通过打破依赖关系并避免不必要的对象和层耦合来帮助您实现这一目标。 所以,基本上你将有一个数据访问层,它将你的应用程序从底层数据层抽象出来,你的应用程序不需要知道数据库是存储在MS SQL数据库,XML文件,文件系统还是物理上仓库。

如果比萨饼和商店在数据库中,则不需要使用设计模式。

这是对设计模式的错误解释。 比萨应该存储在比萨表中,商店应该存储在商店表中。 您应该有一个数据访问层来管理这些数据并将它们转换为POCO数据实体。 您可以手动或使用流行的ORM工具(如NHibernate或Entity Framework)执行此操作

使用设计模式,但是每个Pizza或Store创建一个类,只需创建一个从数据库读取数据的类实现(例如DatabasePizza和DatabaseStore!)。

像这样的东西,你应该有DatabasePizza(你命名)实现一个接口并从数据库中读取数据并公开一些方法,那么你将有一个PizzaEntity只是一个POCO对象,具有Id,Name,Price等属性, etc ...然后你的工厂对象将“服务”构造这个DatabasePizza对象......这里是一个简约的例子......

public static DataFactory
{
    public static IDatabasePizza DatabasePizza
    {
        get{ return new DatabasePizza;}
    }
}

然后客户端应用程序,或存储库,或服务,或业务层可以像这样调用此工厂对象...

IList<PizzaEntity> favouritePizzas = DataFactory.DatabasePizza.GetMyFavouritePizzas();

希望你能理解设计模式背后的想法。 我建议你阅读GoF关于设计模式的书,它是一个很好的信息来源,它附带了一些你可以浏览源代码的项目

有关设计模式的任何示例都只是一个简单的示例或说明。 它们通常使用硬编码值来保持范围较小(而不是查询数据库)。 例如,许多案例似乎不正确或不太适合现实生活需要。

以你的CheesePizzaVeggiePizza 两者都是数据库中Pizza表的2条主记录。 这是正确的,到目前为止还没有设计模式,只需要一个Pizza类实体。

现在随着业务的增长,你将需要另一种Pizza而不是原始Pizza 假设新类是PizzaWithAdditionalTopping 从现在开始,装饰器或策略或工厂设计模式将开始闪耀,因为新类 - IAdditionalToppingAblePizzaWithAdditionalTopping )现在将具有额外的属性IEnumerable<Topping> Toppings ,其中需要专门处理并与Pizza不同。

假设业务再次增长,现在你有一个IStuffedCrustAbleStuffedCrustedPizza )披萨。 现在StuffedCrustedPizza类将有另一个属性string StuffedCrustType (或使用枚举)。 再次使用这些设计模式,希望他们可以在不修改现有代码的情况下添加行为。

您也可以进行其他设计,甚至可以将Toppings添加到原始的Pizza类,或使用if-else, DataTable或任何没有设计模式的设计,但根据经验,可维护性会降低。

如果比萨饼和商店在数据库中,则不需要使用设计模式。

您对设计模式的使用不应受存储/保留数据的方式的影响。 设计模式可帮助您解决已知和精炼解决方案的常见问题。 存储数据的位置/方式与您使用的模式无关。

使用设计模式,但是每个Pizza或Store创建一个类,只需创建一个从数据库读取数据的类实现(例如DatabasePizza和DatabaseStore!)

设计您的模型,以便解决您的业务问题。 不要设计存储模型。 那不是OO。 让ORM或您自己的持久性技术处理将数据打入和取出磁盘的肮脏业务。

如果装饰成分的复合材料的NyPizza是商业问题的正确模型,那么就这样做。 不要让持久性影响你的模型。 有时候必须做出一些权衡:某些ORM有某些怪癖。 但是,模型及其使用的任何设计模式应该是独立的,并且与持久性无关。

我没有研究模式,但我正在这样做:我处理差异机器,所以我实现了一个带有通用代码的类(id,tag,机器之间的链接),然后还有一个地图; 在db中创建了一个名为子类的表,添加了基本行和映射(使用键作为列名。显然,映射键几乎不会更改为子类,因为它必须用alter table处理,这样我就有了各种机器的表格。数据加载方式;你给出类的名称,女巫也是表名,地图加载到列表中,然后谁需要那个info在特定类的构造函数中传递地图。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM