5

我已经根据数据库中的表定义了模型。现在有一些模型的数据几乎没有变化。例如,一个电子商务网站销售的产品的类别,它运送产品的城市等。这些不会经常变化,因此为了避免撞到数据库,这些目前保存为静态变量。

问题是这些静态变量应该在代码中的什么位置。目前,在 ProductCategory 类(也是模型表示)中定义了一个静态列表,如果为空则调用 db 并加载产品类别。同样,City 类也有类似的静态 List 等。

然后在整个应用程序中使用这些静态列表。我正在考虑创建一个名为 StaticData 的类,然后将所有静态列表保留在该类中。那是现在而不是

ProductCategory.AllCategories.Find(p => p.Id = 2) 

我会有

StaticData.AllProductCategories.Find(p => p.Id = 2) 

您认为哪种方法更好?我的目标也是可测试性和解耦代码。

另外,有没有更好的方法来实现这些?你如何在你的代码中做类似的事情?

4

3 回答 3

3

我认为您应该使用Cache而不是静态变量。

我不知道有关您的代码的任何详细信息,因此如果您使用的是存储库,则可以执行以下操作:

if [cache contains object or collection I need]
{
   return [object or collection from cache]
}
else
{
   [get object or collection from database]
   [save object or collection in cache]
   return [object or collection from database]
}

然后,如果您更改缓存实体,您必须找到一种方法来删除这些缓存条目以从数据库中检索新数据。

于 2012-06-28T08:00:03.063 回答
3

如果它足够静态,可以编译到您的代码中,并且永远不必在运行时更改,您可以使用静态类,例如将枚举转换为类的常见模式。

像这样的东西在你的场景中应该可以很好地工作:

public class Vehicle
{
    public static Vehicle Car = new Vehicle("Car");
    public static Vehicle MotorBike = new Vehicle("MotorBike");
    public static Vehicle PeopleMover = new Vehicle("PeopleMover");

    private Vehicle(string name)
    {
        this.name = name
    }
    private string name;
}

使用带有静态成员的枚举或类也应该可以帮助您摆脱代码中那些讨厌的幻数,但是看到那里的语法不正确(缺少一个=)我会假设这只是示例代码,并且在您的真实代码库中看起来不像任何东西。

如果有时确实发生更改,并且您希望数据库中的类别列表,它们可以被紧密缓存(就像几乎永远不会过期,但在更新时手动失效)。根据类别列表的大小,我会考虑将整个集合放在一个大缓存中,并为各个类别查询缓存对象,而不是为每个类别保留一个单独的缓存条目。

于 2012-06-28T08:03:00.440 回答
3

没有简单的答案。您有多种选择,您必须考虑哪一种更适合您的应用:

  • 您可能会使用某种缓存。

    如果产品类别不经常变化,可能太复杂了。当您遇到性能问题(经常阅读数千个类别)并且产品类别经常更改时,这是理想的选择。您可以从任何开源缓存系统中受益,但此解决方案可能更复杂。

  • 您可以将它们硬编码为枚举。

    只有当您 100% 确定产品类别永远不会改变时才好……永远!

  • 您可能有一个 Lazy Singleton 或 Static 类。(我的首选)

    恕我直言,最佳实践可能是有一个 Lazy Singleton 或静态 ProductCategory 类。如果您的数据很少不经常更改,例如可能会在发布时更改,则非常理想。有两种方法:

    在初始化中加载:静态变量应作为常量保存在业务逻辑层中,在您的情况下,您可以在应用程序启动时预加载产品类别并始终保持它们。在这种方法中,您将时间花在应用程序加载上。

    首次使用时加载:第一次尝试访问类别时,请检查它们是否已加载。如果没有,类加载它们。在这种方法中,您会在需要访问产品类别的第一时间花费时间。

    在这两种方法中的任何一种中,每次应用程序池重新启动后数据都会丢失,因此如果您发布新版本,您将刷新数据。在数据库“紧急”更新的情况下,您可以随时重新启动应用程序池。

于 2012-06-28T08:07:14.187 回答