为条件编程避免访问静态表数据的冗余

时间:2021-01-12 16:00:20

I've the following scenario. My application interacts with the database which contains some static tables. If I have to use that static information in the code level mostly for conditional code, what is the best approach.

我下面的场景。我的应用程序与包含一些静态表的数据库交互。如果我必须在代码级别上使用静态信息,主要是针对条件代码,那么最好的方法是什么?

For eg: I've a student database, which contains a static table student_type ( indicating hard-working, smart, lazy etc types ). In the code, I need to take action based on the student_type.

例如:我有一个学生数据库,其中包含一个静态表student_type(表示勤奋、聪明、懒惰等类型)。在代码中,我需要基于student_type采取操作。

So, my code would look like this

我的代码是这样的

studentTypeId = student.getTypeId(); // student constructed from database
switch (studentTypeId)
{
    case HARDWORKING_ID :
       // do something
    case LAZY_ID :
       // do something
    break;
}

Well, in my code, I would either use constants or an enum to store type ids. But, isn't this kind of replicating things in code since I already have type ids in database. If the type id in database changes I'll have to change the same in my Enum which increases maintenance. Is there a better way to achieve this?

在我的代码中,我要么使用常量,要么使用enum来存储类型id。但是,这不是在代码中复制的东西,因为我已经在数据库中有了类型id。如果数据库中的类型id发生更改,我必须在Enum中更改相同的内容,以增加维护。有没有更好的方法来实现这个目标?

Thanks.

谢谢。

3 个解决方案

#1


2  

The question to ask is: does the addition of the row in the database imply a change in your java? If yes, go for the enum approach, and don't worry about the duplication. If you're going to have to change code anyway, for instance, to add new cases to your switch, then I usually find it's a good idea to keep things simple.

问题是:在数据库中添加行是否意味着java中发生了更改?如果是,那么使用enum方法,不要担心重复。如果你无论如何都要修改代码,例如,在你的交换机中添加新情况,那么我通常认为保持简单是一个好主意。

studentTypeId = student.getTypeId(); // student constructed from database
switch (studentTypeId)
{
    case HARDWORKING_ID :
       // do something
    case LAZY_ID :
       // do something
    case SMART_ID :     // added smart student, very rare corner case :-)
       // do something
    break;
}

Often in cases where you're storing static data like this you've got other constraints that go with the data, and when you change the data in the database, you have to change the code that uses that data.

在存储静态数据的情况下,通常会有与数据相关的其他约束,当您更改数据库中的数据时,您必须更改使用该数据的代码。

If you really really want to reduce the duplication, then you can go for a fully pluggable architecture, as suggested by Dave Newton. This could be implemented as a id -> class name relation for each id. You'd then instantiate the class and all of the logic associated with each id would be contained in that class. This isn't always easy or possible. For your example, it may well be possible, but unless it's done right, this can be complicated.

如果你真的想减少重复,那么你可以采用完全可插拔的架构,就像戴夫·牛顿(Dave Newton)建议的那样。这可以实现为每个id的id ->类名关系,然后实例化类,与每个id相关的所有逻辑都包含在这个类中。这并不总是容易或可能的。对于您的示例,它很可能是可能的,但是除非它做得很好,否则这可能会很复杂。

Also, it doesn't solve all of your problems. You still have to develop the java, test it, and redeploy the new class. So actually, the amount of work you would save may be minimal.

而且,它也不能解决你所有的问题。您仍然需要开发java、测试它并重新部署新类。因此,实际上,你可以节省的工作量可能是最小的。

It's often easier to accept the small amount of duplication and just go with the simple solution.

通常更容易接受少量的重复,只使用简单的解决方案。

#2


1  

If the student_type table contains only some ID's and perhaps some descriptive text but nothing more as in this small example

如果student_type表只包含一些ID,或者一些描述性的文本,但是不能像这个小示例那样包含更多的内容

   ID    description
    1    'Hard worker'
    2    'Lazy snob'

then your only chance is to use the IDs in your code, perhaps giving them proper names using either an enum or some constant interface as you did already. And every change on `student_type' which requires a change in behaviour will require code changes. There is no way out, because the only place where behaviour is formalized and defined is in your code.

然后,您唯一的机会是在代码中使用id,可能使用enum或常量接口为它们提供适当的名称,就像您已经做过的那样。而“student_type”上的每一个改变都需要改变行为,这就需要代码的改变。没有出路,因为行为被形式化和定义的唯一地方是在代码中。

IF however the table has formalized content like here

但是,如果该表具有如下所示的形式化内容

   ID    description    min_    max_   min_  max_  fire_   give_
                      points  points  grade grade  ASAP    kudos
    1    'Hard worker'   100     200      B     A     F        T
    2    'Lazy snob'       0      50      Z     Q     T        F
    3    'Medium'         50     100      P     C     F        F

then the behaviour of your app is not driven by the ID but by the associated data - the data forms a simple rule system. In that case you don't need any constants in your code, because you will implement the rule system like this:

然后,应用程序的行为不是由ID驱动的,而是由相关数据驱动的——数据形成了一个简单的规则系统。在这种情况下,代码中不需要任何常量,因为您将实现如下规则系统:

    StudentType studentType = student.getStudentType();
    if( studentType.isGiveKudos() )
        doGiveKudos(student);
    if( studentType.isFireAsap() )
        doFire(student);
    // next student...

This is the way to go if the flexibility is a must.

如果灵活性是必须的,那么这就是解决之道。

scratch head Now I don't know if this deviates to much from the question.

现在我不知道这个问题是否偏离了很多。

#3


0  

There's a bunch of ways this could be implemented. For quick/dirty stuff I'll often store the class name of an implementation in the DB and just instantiate at runtime. Sometimes I'll keep a Groovy implementation in the DB. Sometimes I'll use Spring beans where the factory is stored in the DB. All depends.

有很多方法可以实现这个。对于快速/脏的东西,我通常将实现的类名存储在DB中,并在运行时实例化。有时我会在DB中保留一个Groovy实现。有时我会使用存储在DB中的Spring bean。要看情况而定。

#1


2  

The question to ask is: does the addition of the row in the database imply a change in your java? If yes, go for the enum approach, and don't worry about the duplication. If you're going to have to change code anyway, for instance, to add new cases to your switch, then I usually find it's a good idea to keep things simple.

问题是:在数据库中添加行是否意味着java中发生了更改?如果是,那么使用enum方法,不要担心重复。如果你无论如何都要修改代码,例如,在你的交换机中添加新情况,那么我通常认为保持简单是一个好主意。

studentTypeId = student.getTypeId(); // student constructed from database
switch (studentTypeId)
{
    case HARDWORKING_ID :
       // do something
    case LAZY_ID :
       // do something
    case SMART_ID :     // added smart student, very rare corner case :-)
       // do something
    break;
}

Often in cases where you're storing static data like this you've got other constraints that go with the data, and when you change the data in the database, you have to change the code that uses that data.

在存储静态数据的情况下,通常会有与数据相关的其他约束,当您更改数据库中的数据时,您必须更改使用该数据的代码。

If you really really want to reduce the duplication, then you can go for a fully pluggable architecture, as suggested by Dave Newton. This could be implemented as a id -> class name relation for each id. You'd then instantiate the class and all of the logic associated with each id would be contained in that class. This isn't always easy or possible. For your example, it may well be possible, but unless it's done right, this can be complicated.

如果你真的想减少重复,那么你可以采用完全可插拔的架构,就像戴夫·牛顿(Dave Newton)建议的那样。这可以实现为每个id的id ->类名关系,然后实例化类,与每个id相关的所有逻辑都包含在这个类中。这并不总是容易或可能的。对于您的示例,它很可能是可能的,但是除非它做得很好,否则这可能会很复杂。

Also, it doesn't solve all of your problems. You still have to develop the java, test it, and redeploy the new class. So actually, the amount of work you would save may be minimal.

而且,它也不能解决你所有的问题。您仍然需要开发java、测试它并重新部署新类。因此,实际上,你可以节省的工作量可能是最小的。

It's often easier to accept the small amount of duplication and just go with the simple solution.

通常更容易接受少量的重复,只使用简单的解决方案。

#2


1  

If the student_type table contains only some ID's and perhaps some descriptive text but nothing more as in this small example

如果student_type表只包含一些ID,或者一些描述性的文本,但是不能像这个小示例那样包含更多的内容

   ID    description
    1    'Hard worker'
    2    'Lazy snob'

then your only chance is to use the IDs in your code, perhaps giving them proper names using either an enum or some constant interface as you did already. And every change on `student_type' which requires a change in behaviour will require code changes. There is no way out, because the only place where behaviour is formalized and defined is in your code.

然后,您唯一的机会是在代码中使用id,可能使用enum或常量接口为它们提供适当的名称,就像您已经做过的那样。而“student_type”上的每一个改变都需要改变行为,这就需要代码的改变。没有出路,因为行为被形式化和定义的唯一地方是在代码中。

IF however the table has formalized content like here

但是,如果该表具有如下所示的形式化内容

   ID    description    min_    max_   min_  max_  fire_   give_
                      points  points  grade grade  ASAP    kudos
    1    'Hard worker'   100     200      B     A     F        T
    2    'Lazy snob'       0      50      Z     Q     T        F
    3    'Medium'         50     100      P     C     F        F

then the behaviour of your app is not driven by the ID but by the associated data - the data forms a simple rule system. In that case you don't need any constants in your code, because you will implement the rule system like this:

然后,应用程序的行为不是由ID驱动的,而是由相关数据驱动的——数据形成了一个简单的规则系统。在这种情况下,代码中不需要任何常量,因为您将实现如下规则系统:

    StudentType studentType = student.getStudentType();
    if( studentType.isGiveKudos() )
        doGiveKudos(student);
    if( studentType.isFireAsap() )
        doFire(student);
    // next student...

This is the way to go if the flexibility is a must.

如果灵活性是必须的,那么这就是解决之道。

scratch head Now I don't know if this deviates to much from the question.

现在我不知道这个问题是否偏离了很多。

#3


0  

There's a bunch of ways this could be implemented. For quick/dirty stuff I'll often store the class name of an implementation in the DB and just instantiate at runtime. Sometimes I'll keep a Groovy implementation in the DB. Sometimes I'll use Spring beans where the factory is stored in the DB. All depends.

有很多方法可以实现这个。对于快速/脏的东西,我通常将实现的类名存储在DB中,并在运行时实例化。有时我会在DB中保留一个Groovy实现。有时我会使用存储在DB中的Spring bean。要看情况而定。