如何使用oop和soc实现从数据库读取默认对象设置

发布于 2024-11-18 21:42:15 字数 1470 浏览 1 评论 0 原文

我有一个如下所示的类:

public class Location {
    private int id;
    private String name = "noname";
    ... // other properties

    public Location(int locationId) {
        this.id = locationId;
        this.name = getNameFromDatabase(locationId);
    } 

    public static Map<Integer,Location> getAllLocations() {
        // reads all locations from database and puts objects into a map
    }       

    ... // other methods

}

name 属性可以使用以下方式之一定义:

  1. 开发人员在源代码中定义的默认值
  2. 数据库中定义的默认应用程序值(覆盖开发人员的默认值)、
  3. 位置特定值在数据库中定义(覆盖之前的两个值)

在应用程序中,位置对象由 Map 实例化。 locations = Location.getAllLocations();

实现 1. 和 3. 很简单,但是实现 2.“应用程序特定的默认值”的最合适方法是什么

  • 我可以在 getNameFromDatabase 方法中获取默认值,但随后我会在数据库中为每个新位置寻找默认值(因为它是默认值,所以应该只选择一次)

  • 在位置对象实例化中,我可以事先将默认值读取到特殊位置对象中,然后将该对象传递给构造函数(但我确实相信我会破坏关注点分离)

  • 我相信我需要某种静态单例,它将在类内实例化,但我不知道如何实现它

    编辑

  • 显示的名称属性只是整个类的一个片段(大约有20个属性)

  • 默认应用程序值也存储在数据库中;事实上,它与其他位置位于同一个表中,只是它有一个特殊的 id -1;所以我目前在 getNameFromDatabase 方法中所做的是 select * from location where location_id in (-1, &lt;locationid&gt;) order by location_id,但我确实认为这是一个糟糕的设计,因为我正在读取我设置的每个位置的默认位置值

  • 所以我正在寻找的是:在 getnamefromdatabase 方法中,它首先检查是否为我的位置 id 定义了名称。如果没有,请检查我是否已经定义了全局默认位置名称,如果没有,请在数据库中找到它,然后定义全局默认位置名称。

I have a class which looks like this:

public class Location {
    private int id;
    private String name = "noname";
    ... // other properties

    public Location(int locationId) {
        this.id = locationId;
        this.name = getNameFromDatabase(locationId);
    } 

    public static Map<Integer,Location> getAllLocations() {
        // reads all locations from database and puts objects into a map
    }       

    ... // other methods

}

The name property can be defined in one of the following ways using:

  1. default value defined by the developer in the source code
  2. default application value defined in the database (overrides the developer's default),
  3. location specific value defined in the database (overrides both previous' values)

In the application the location object is instantiated by Map<Integer,Location> locations = Location.getAllLocations();

Implementing 1. and 3. is straightforward, but what is the most appropriate way to implement the 2. "application specific default values":

  • I can get the default value in the getNameFromDatabase method, but then I am seeking for a default value in the database with each and every new location (since it's default, it should be selected only once)

  • In location object instantiation I could beforehand read default values into a special location object and then pass this object to the constructor (but I do believe I'd be breaking the separation of concerns)

  • I believe I'd need sort of static singleton which would be instantiated inside the class, but I have no idea how to implement it

    EDIT

  • the shown name property is just a snippet from a whole class (there are about 20 properties)

  • default application value is also stored in the database; in fact it is in the the same table as other locations, except it has a special id -1; so what I am currently doing in getNameFromDatabase method is select * from location where location_id in (-1, <locationid>) order by location_id, but I do believe it is a bad design, since I am reading default location values for each and every location I set

  • so what I am looking for is: in method getnamefromdatabase, it first checks if there is a name defined for my location id. if not, check if I already have a globaly defined defaultlocationname, if not, find it in database and then define global defaultlocationname.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦一生花开无言 2024-11-25 21:42:15

如果您已正确定义 getNameFromDatabasegetApplicationDefaultName 方法,则应执行类似以下操作的操作。 (还应该定义 setApplicationDefaultName 方法来设置给定 locationId 的应用程序名称)

private int id;
private String name =- "noname"; // default in source code?

public Location(int locationId) {
    // ...
    String appName = Location.getApplicationDefaultName();
    String dbName = getNameFromDatabase(locationId);
    if(dbName != null) {
        this.name = dbName;
    } else if (appName != null) {
        this.name = appName;
    } // else name will default to initially set value.
}

当您使用语句 this.name = getNameFromDatabase(locationId) 分配名称时,您覆盖之前分配给 this.name 的值,因此您的情况 1 将不会实现。您分配名称(或任何具有由第 1,2 点和第 3 点描述的预期行为的属性)的逻辑应该是:

if (db has specific name)
    use db specific name              // point 3
else if (db has default name)         // point 2
    use db default name
else
    don't overwrite source code name  //point 1

编辑

分离检索名称的关注点的一种方法您用于检索该值的实践中的默认数据库值(每个虚拟机一次,或每次,或有时取决于月相)是使用 策略设计模式。接口 RetrievalMethod 应该有一个方法 getDefaultFromDatabase(),其行为可由实现者指定。执行此操作后,您的位置的 getApplicationDefaultName 方法(以及 RetrievalMethod 策略设置方法)将如下所示:

private RetrievalMethod myLocationRetriever = GenericRetrievalMethod(/*...*/);
// ...
public void setLocationRetrievalMethod(RetrievalMethod retr) {
    myLocationRetriever = retr;
}
// ... 
private String getApplicationDefaultName() {
    myLocationRetriever.getDefaultFromDatabase();
}

根据您的应用程序规范,您可以设置 myLocationRetriever到适当的行为。

Something like the following should do it, if you have appropriately defined getNameFromDatabase and getApplicationDefaultName methods. ( a setApplicationDefaultName method should also be defined for setting the application's name for a given locationId )

private int id;
private String name =- "noname"; // default in source code?

public Location(int locationId) {
    // ...
    String appName = Location.getApplicationDefaultName();
    String dbName = getNameFromDatabase(locationId);
    if(dbName != null) {
        this.name = dbName;
    } else if (appName != null) {
        this.name = appName;
    } // else name will default to initially set value.
}

When you assign name with the statement this.name = getNameFromDatabase(locationId), you are overwriting the value previously assigned to this.name, so your case 1 will not be realized. Your logic for assigning the name (or any of your properties with the expected behavior to be described by your points 1,2, & 3) should be:

if (db has specific name)
    use db specific name              // point 3
else if (db has default name)         // point 2
    use db default name
else
    don't overwrite source code name  //point 1

Edit

One way of separating the concern of retrieving the default database value from what practice you use to retrieve that value (once per VM, or every time, or just sometimes depending on the phase of the moon) is by using the Strategy design pattern. The interface RetrievalMethod should have one method, getDefaultFromDatabase(), whose behavior can be specified by implementers. Doing this, your Location's getApplicationDefaultName method (along with the RetrievalMethod strategy setting method) will look like:

private RetrievalMethod myLocationRetriever = GenericRetrievalMethod(/*...*/);
// ...
public void setLocationRetrievalMethod(RetrievalMethod retr) {
    myLocationRetriever = retr;
}
// ... 
private String getApplicationDefaultName() {
    myLocationRetriever.getDefaultFromDatabase();
}

Per your application specs, you can set myLocationRetriever to the appropriate behavior.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文