- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在努力解决过去几个月一直困扰我的难题。
我和我的同事在一个技术问题上完全不同意,我想听听我们亲爱的社区对此事的看法。
使用枚举(具有潜在的属性,例如“描述”)还是使用实体(具有名称和描述属性)更好?
在我们的领域模型中,我们有很多微型实体,它们只包含一个 ID、一个名称和一个描述。95% 的情况下,描述等同于名称。
为了便于解释,我将举一个例子:在我们的 Security 实体中,我们有一个 AssetClass 属性。AssetClass 具有静态值列表(“股权”、“债券”等),并且不会因界面或其他任何内容而发生变化。
问题在于,当您想要获得 Assets 类别为“Bond”的所有证券时,例如,NHibernate 将必须加入 AssetClass 表...并且考虑到 AssetClass 不是唯一的属性,您可以想象所有这些连接对性能的影响。
我们的代码中有一些 AssetClass 的硬编码实例及其各自的值和 ID(即 ID 为 1 的股票,ID 为 2 的债券等),它们与数据库中的内容相匹配:
public partial class AssetClass
{
static public AssetClass Equity = new AssetClass(1, "Equity", "Equity");
static public AssetClass Bond = new AssetClass(2, "Bond", "Bond");
static public AssetClass Future = new AssetClass(3, "Future", "Future");
static public AssetClass SomethingElse = new AssetClass(4, "Something else", "This is something else");
}
我们还制作了一个特殊的 NHibernate 类型(如果您有兴趣,请在下面编写代码)它允许我们通过加载该硬编码实例而不是去数据库获取它来避免 NHibernate 进行连接:
using System;
using System.Data;
using System.Data.Common;
using NHibernate.Dialect;
using NHibernate.SqlTypes;
using NHibernate.Type;
namespace MyCompany.Utilities.DomainObjects
{
public abstract class PrimitiveTypeBase<T> : PrimitiveType where T : class, IUniquelyNamed, IIdentifiable
{
private readonly PrimitiveTypeFactory<T> _factory;
public PrimitiveTypeBase() : base(SqlTypeFactory.Int32)
{
_factory = new PrimitiveTypeFactory<T>();
}
public override string Name
{
get { return typeof(T).Name; }
}
public override Type ReturnedClass
{
get { return typeof(T); }
}
public override Type PrimitiveClass
{
get { return typeof (int); }
}
public override object DefaultValue
{
get { return null; }
}
public override void Set(IDbCommand cmd, object value, int index)
{
var type = value as T;
var param = cmd.Parameters[index] as DbParameter;
param.Value = type.Id;
}
public override object Get(IDataReader rs, int index)
{
return GetStaticValue(rs[index]);
}
public override object Get(IDataReader rs, string name)
{
return GetStaticValue(rs[name]);
}
private T GetStaticValue(object val)
{
if (val == null)
{
return (T)DefaultValue;
}
int id = int.Parse(val.ToString());
T entity = _factory.GetById(id); // that returns, by reflection and based on the type T, the static value with the given Id
if (entity == null)
{
throw new InvalidOperationException(string.Format("Could not determine {0} for id {1}", typeof (T).Name, id));
}
return entity;
}
public override object FromStringValue(string xml)
{
return GetStaticValue(xml);
}
public override string ObjectToSQLString(object value, Dialect dialect)
{
var type = value as T;
return type.Id.ToString();
}
}
}
用枚举替换这些实体,如果我们需要描述字段,请使用属性。我们还可以对数据库进行约束,以确保您不能存储与枚举不匹配的随机值。
现在,您怎么想?
最佳答案
就我个人而言,我更喜欢第一种解决方案,可能带有一个返回所有值的附加属性。
它更面向对象 - 枚举基本上是“命名数字”,仅此而已。在代码的其他任何地方,状态都存储在属性中——那么为什么要使用属性呢?正如 Eric Lippert 在 blog post comparing the two 中所写,“属性是关于机制的事实”。您基本上是将它们用作提供有关值(value)观的数据的一种方式,我觉得这不对。
就代码和数据库之间的潜在不匹配而言,您反对使用 POCO 的前两个反对意见也不成立 - 因为它们对于枚举也完全相同,不是吗?此外,编写验证数据的测试非常容易 - 如果需要,您甚至可以在启动时这样做。
尚不清楚 AssetClass
的其余部分的作用,但如果它只有一个 private 构造函数,那么您将在以下方面获得枚举的很多好处一组有限的、众所周知的值,但没有枚举基本上只是数字的问题。
事实上,POCO 解决方案在值限制方面优于 - 因为唯一“无效”的 POCO 值是 null,而很容易得出无效的枚举值:
FooEnum invalid = (FooEnum) 12345;
您要到处检查吗?通常,空引用比无效枚举值更早发生爆炸,并且也更容易检查。
我能想到的 POCO 方法的一个缺点是您无法打开它。有很多方法可以解决这个问题,但它们并不是非常令人愉快 - 你基本上必须还有一组众所周知的数字(当然可以是一个枚举)以便一些属性会返回它,你可以打开它。
关于c# - 意见请求 : for static values, 使用枚举或实体更好吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7119175/
我是 F# 的菜鸟,目前正在阅读 F# 3.0 中的专家。 它是我学习的第一种编译语言(我只知道用 R 编程) 在第 6 章第 117 页,我们没有太多仪式性地介绍 静态让和静态成员。我真的不明白它是
我很迷茫。我已经花几个小时广泛地复习了我的两个类(class)。没有什么是静态的,没有什么是静态引用的,但我无法摆脱这个错误。 A 类文件 (ClassA.php) privateVariable =
关于类公共(public)类声明,请看这两段代码: public class Helper { public static void CallMeganFox(string phoneNumb
我如何使用“super”关键字从父类(super class)(类“aa”)引用“a1” class aa { protected static int a1 = 2; } public class
class Perkusja { boolean talerze = true; boolean beben = true; void zagrajNaBebnie() { Sys
我试图在编译 C++ 程序时静态链接库。 g++ (GCC) 4.8.5 20150623(红帽 4.8.5-4) $ g++ -std=c++11 -I/home/jerry/Desktop/tin
$ javac TestFilter.java TestFilter.java:19: non-static variable this cannot be referenced from a sta
这个问题在这里已经有了答案: How do I create a global, mutable singleton? (7 个答案) How can you make a safe static
“覆盖”静态数组时我遇到了一个棘手的问题。我有静态数组(为简单起见),它们在不同的派生类中具有固定长度,但在编译时仍然知道所有大小。我在基类中也有一个虚函数,但我不知道如何解决在派生类中覆盖这些数组和
我刚刚在遗留代码中发现了这一点。我知道使用宏,每当使用名称时,它都会被宏的内容替换。它们最常用于为数字常量提供符号名称。我所知道的是预处理没有类型安全、范围的概念。 这样做的真正好处是什么? #def
将 Singleton 实例声明为 static 还是声明为 static final 更好? 请看下面的例子: 静态版本 public class Singleton { private s
问题: 我观察到的行为是 TypeScript 的预期行为吗? 我观察到的行为是 ECMAScript 6 的预期行为吗? 是否有一种简单的方法可以返回继承层次结构以处理每个级别的“myStatic”
在php中,访问类的方法/变量有两种方法: 1. 创建对象$object = new Class(),然后使用”->”调用:$object->attribute/functi
我尝试向 ExpandoObject 添加一个动态方法,该方法会返回属性(动态添加)给它,但它总是给我错误。 我在这里做错了吗? using System; using System.Collecti
我试图获得一个静态链接到我的程序的音频库。我用 this灵活的包。为了让它运行,我必须按照描述构建 soloud 库 here .下载后不久,我在“build”文件夹中运行了“genie --with
这是我的webpack.prod.config.js代码 const path = require('path'); const { CleanWebpackPlugin } = require('c
我想知道什么时候应该对变量和(或)方法使用静态、最终、静态最终参数。据我了解: final:类似于c++中的const参数。它基本上意味着值(或在方法中 - 返回值)不会改变。 静态:这意味着值(或方
我一直在阅读有关使用静态对象作为锁的内容,最常见的示例如下: public class MyClass1 { private static final Object lock = new Obje
在 Visual Basic 2008 中,我知道有两种不同的方法可以完成同一件事: 成员(member)级别的 Dim: Dim counter1 as integer = 0 Dim counte
static public final int i = 0; public static final int i = 0; 两者都工作正常。 为什么同样的事情可以用两种不同的风格来完成? 最佳答案 因
我是一名优秀的程序员,十分优秀!