它是使用反射在业务逻辑中好的做法呢?它是、反射、逻辑、做法

2023-09-03 16:12:05 作者:sI淰ɡцδー秒…

我需要工作,它由两个主要部分的应用程序:

I need to work on an application that consists of two major parts:

在业务逻辑部分的具体业务类(如图书,图书馆,作者,...) 在一个普通的一部分,可以显示书籍,图书馆,...在数据网格,它们映射到数据库,...)。

通用部分使用反射来获取数据的业务类别,而不需要编写特定的数据网格或数据库逻辑的业务类。这工作得很好,并允许我们无需调整数据网格和数据库逻辑增加新的业务类(如LibraryMember)。

The generic part uses reflection to get the data out of the business classes without the need to write specific data-grid or database logic in the business classes. This works fine and allows us to add new business classes (e.g. LibraryMember) without the need to adjust the data grid and database logic.

然而,多年来,code加入到业务类也使用反射来得到的东西在业务类完成的。例如。如果一本书的作者发生变化时,观察家们打电话告诉了作者本身,它应该此书添加到书是他写的(Author.Books)的集合。在这些观察,不仅实例被传递,而且信息是直接来自于反射(该字段信息被添加到观察者呼叫,使得在调用方知道书的领域作者被改变)。

However, over the years, code was added to the business classes that also makes use of reflection to get things done in the business classes. E.g. if the Author of a Book is changed, observers are called to tell the Author itself that it should add this book to its collection of books written by him (Author.Books). In these observers, not only the instances are passed, but also information that is directly derived from the reflection (the FieldInfo is added to the observer call so that the caller knows that the field "Author" of the book is changed).

我可以清楚地看到优势,在这些通用组件(如数据网格或数据库接口)使用反射,但在我看来,在业务类使用反射是一个坏主意。毕竟,不应该不依赖于反射尽可能多地申请工作?或者是利用反射在21世纪的'工作的正常方式?

I can clearly see advantages in using reflection in these generic modules (like the data grid or database interface), but it seems to me that using reflection in the business classes is a bad idea. After all, shouldn't the application work without relying on reflection as much as possible? Or is the use of reflection the 'normal way of working' in the 21st century?

它是很好的做法,使用反射在你的业务逻辑?

Is it good practice to use reflection in your business logic?

修改:一些澄清柯克的一句话:

EDIT: Some clarification on the remark of Kirk:

想象一下,作者实现了对图书的观察​​员。 立即调用它的所有观察者,只要书的某些领域改变(如标题,年份,#Pages,作者,...)。改变字段的字段信息传入的观察者。 的作者观察员然后使用这个字段信息,以决定是否有兴趣在这个变化。在这种情况下,如果字段信息为预定的字段作者,作者-观察员将更新其自己的书籍的矢量。

推荐答案

我避免使用反射。是的,它使你的程序更加灵活。但这种灵活性是以高昂的代价:有没有编译时检查字段名称或类型或其他信息,你收集通过反射

I avoid using reflection. Yes, it makes your program more flexible. But this flexibility comes at a high price: There is no compile-time checking of field names or types or whatever information you're collecting through reflection.

很多事情一样,这取决于你在做什么。如果你的逻辑的本质是,你永远比发现一个恒定值的字段名(或其他),然后利用反射可能是一件好事。但是,如果你通过他们使用反射找到字段名称,然后循环搜索名为作者和名称字段,你刚刚创建了一个更复杂的模拟对象的两个命名字段。如果你搜索作者的时候,场实际上是所谓的AUTHORNAME什么,或者你打算搜索作者,不慎输入Auhtor?现在你有错误,会不会出现,直到运行时,而不是被标记在编译时。

Like many things, it depends on what you're doing. If the nature of your logic is that you NEVER compare the field names (or whatever) found to a constant value, then using reflection is probably a good thing. But if you use reflection to find field names, and then loop through them searching for the fields named "Author" and "Title", you've just created a more-complex simulation of an object with two named fields. And what if you search for "Author" when the field is actually called "AuthorName", or you intend to search for "Author" and accidentally type "Auhtor"? Now you have errors that won't show up until runtime instead of being flagged at compile time.

使用硬codeD字段名,你的IDE可以告诉你,某个字段用于每一个地方。与反思......没那么容易分辨。也许你可以做名称的文本搜索,但如果字段名被传来传去的变量,它可以变得非常困难。

With hard-coded field names, your IDE can tell you every place that a certain field is used. With reflection ... not so easy to tell. Maybe you can do a text search on the name, but if field names are passed around as variables, it can get very difficult.

我的工作系统现在所在的原作者喜爱的反思和类似技术的。有各种各样的地方,他们需要创建一个类的实例,而不是只说:新的和类,它们创建令牌,他们看起来在一个表中获取类名。这是什么好处?是的,我们可以改变表,该标记映射到一个不同的名字。而这种获得我们...什么?当最后一次,你说:哦,每一个我的程序创建客户的一个实例的地方,我想改变创建NewKindOfCustomer的一个实例。如果有变化的一类,你更改类,而不是创建一个新的类,但各地保持旧的怀旧。

I'm working on a system now where the original authors loved reflection and similar techniques. There are all sorts of places where they need to create an instance of a class and instead of just saying "new" and the class, they create a token that they look up in a table to get the class name. What does this gain? Yes, we could change the table to map that token to a different name. And this gains us ... what? When was the last time that you said, "Oh, every place that my program creates an instance of Customer, I want to change to create an instance of NewKindOfCustomer." If you have changes to a class, you change the class, not create a new class but keep the old one around for nostalgia.

要采取类似的问题,我做在飞行构建数据输入屏幕的常规做法问数据库中的字段名称,类型和大小的列表,然后铺设从那里出来。这给了我使用同样的程序对所有简单的数据输入屏幕的优势 - 只是通过在表名作为参数 - 如果一个字段被添加或删除,零code修改是必要的。但这只只要我不关心什么领域都适用。有一次,我开始有验证或副作用具体到这个画面,该系统是更多的麻烦比它的价值,我最好还是回落至更明确的编码。

To take a similar issue, I make a regular practice of building data entry screens on the fly by asking the database for a list of field names, types, and sizes, and then laying it out from there. This gives me the advantage of using the same program for all the simpler data entry screens -- just pass in the table name as a parameter -- and if a field is added or deleted, zero code change is required. But this only works as long as I don't care what the fields are. Once I start having validations or side effects specific to this screen, the system is more trouble than it's worth, and I'm better off to fall back to more explicit coding.