我有一个如下所示的类:
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 属性可以使用以下方式之一定义:
- 开发人员在源代码中定义的默认值
- 数据库中定义的默认应用程序值(覆盖开发人员的默认值)、
- 位置特定值在数据库中定义(覆盖之前的两个值)
在应用程序中,位置对象由 Map 实例化。 locations = Location.getAllLocations();
实现 1. 和 3. 很简单,但是实现 2.“应用程序特定的默认值”的最合适方法是什么:
-
我可以在 getNameFromDatabase 方法中获取默认值,但随后我会在数据库中为每个新位置寻找默认值(因为它是默认值,所以应该只选择一次)
-
在位置对象实例化中,我可以事先将默认值读取到特殊位置对象中,然后将该对象传递给构造函数(但我确实相信我会破坏关注点分离)
-
我相信我需要某种静态单例,它将在类内实例化,但我不知道如何实现它
编辑
显示的名称属性只是整个类的一个片段(大约有20个属性)
-
默认应用程序值也存储在数据库中;事实上,它与其他位置位于同一个表中,只是它有一个特殊的 id -1;所以我目前在 getNameFromDatabase 方法中所做的是 select * from location where location_id in (-1, <locationid>) 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:
- default value defined by the developer in the source code
- default application value defined in the database (overrides the developer's default),
- 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.
发布评论
评论(1)
如果您已正确定义
getNameFromDatabase
和getApplicationDefaultName
方法,则应执行类似以下操作的操作。 (还应该定义setApplicationDefaultName
方法来设置给定 locationId 的应用程序名称)当您使用语句
this.name = getNameFromDatabase(locationId)
分配名称时,您覆盖之前分配给this.name
的值,因此您的情况 1 将不会实现。您分配名称(或任何具有由第 1,2 点和第 3 点描述的预期行为的属性)的逻辑应该是:编辑
分离检索名称的关注点的一种方法您用于检索该值的实践中的默认数据库值(每个虚拟机一次,或每次,或有时取决于月相)是使用 策略设计模式。接口
RetrievalMethod
应该有一个方法getDefaultFromDatabase()
,其行为可由实现者指定。执行此操作后,您的位置的getApplicationDefaultName
方法(以及RetrievalMethod
策略设置方法)将如下所示:根据您的应用程序规范,您可以设置
myLocationRetriever
到适当的行为。Something like the following should do it, if you have appropriately defined
getNameFromDatabase
andgetApplicationDefaultName
methods. ( asetApplicationDefaultName
method should also be defined for setting the application's name for a given locationId )When you assign name with the statement
this.name = getNameFromDatabase(locationId)
, you are overwriting the value previously assigned tothis.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: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'sgetApplicationDefaultName
method (along with theRetrievalMethod
strategy setting method) will look like:Per your application specs, you can set
myLocationRetriever
to the appropriate behavior.