Design patterns 寻找特定的设计模式
我在寻找一种描述特定情况的模式。也许有人知道些什么,可以给我一个提示 情况类型A的对象,1:n与类型B的对象关联。例如:一个人和他的所有宠物。宠物对象具有年龄数据成员。现在每个人都应该有一个宠物平均年龄的数据成员。我不希望保存和加载这些信息,而是希望在加载过程中计算这些信息(所有必要的信息都已经存在,所以有点多余,但我希望person对象中的信息) 问题那么如何以面向对象的方式实现这一点呢?是否有一种模式可以描述这种情况?我的第一个想法是让ComputedFieldsUpdater类接受一个宠物对象,然后计算所有未加载的字段。但我想知道这是正确的方法还是有更优雅的解决方案Design patterns 寻找特定的设计模式,design-patterns,Design Patterns,我在寻找一种描述特定情况的模式。也许有人知道些什么,可以给我一个提示 情况类型A的对象,1:n与类型B的对象关联。例如:一个人和他的所有宠物。宠物对象具有年龄数据成员。现在每个人都应该有一个宠物平均年龄的数据成员。我不希望保存和加载这些信息,而是希望在加载过程中计算这些信息(所有必要的信息都已经存在,所以有点多余,但我希望person对象中的信息) 问题那么如何以面向对象的方式实现这一点呢?是否有一种模式可以描述这种情况?我的第一个想法是让ComputedFieldsUpdater类接受一个宠物
谢谢您的想法。如果您为关联创建一个类来键入B,那么它相当简单:您仍然需要某种类型的列表。所以只需创建一个“PetList”或类似的东西,它有一个方法“
averageAge()
”,该方法从它的所有pet计算这个值
现在,您可以通过调用person.getPets().averageAge()
访问平均值
从面向对象的角度来看,关于平均值的信息无论如何都不应该直接出现在Person对象中。如果您为关联创建一个类来键入B,那么它相当简单:您无论如何都需要某种列表。所以只需创建一个“PetList”或类似的东西,它有一个方法“
averageAge()
”,该方法从它的所有pet计算这个值
现在,您可以通过调用person.getPets().averageAge()
访问平均值
从面向对象的角度来看,关于平均值的信息无论如何都不应该直接出现在Person对象中。这不是一种四人帮的设计模式,但当绝对需要存储对计算来说是多余的数据时,通常接受的解决方案是延迟加载数据,然后保留一个布尔值来描述它是否仍然有效 换言之:
class Person
{
List<Pet> myPets;
float averageAge;
boolean isAgeValid = false;
float getAverageAge()
{
if(isAgeValid)
return averageAge;
else
...calculate age, save it in averageAge, set bool to true, and return derived float...
}
//all list operations should mark the bool false
void Add(Pet p)
{
myPets.Add(p);
isAgeValid=false;
}
}
班级人员
{
列出我的宠物;
浮动平均数;
布尔值isAgeValid=false;
float getAverageAge()
{
if(isAgeValid)
平均回报率;
其他的
…计算年龄,将其保存在averageAge中,将bool设置为true,然后返回派生的float。。。
}
//所有列表操作都应将bool标记为false
无效添加(Pet p)
{
添加(p);
isAgeValid=false;
}
}
这不是四人一组的设计模式,但当绝对需要存储对计算来说是多余的数据时,通常接受的解决方案是延迟加载数据,然后保留一个布尔值来描述它是否仍然有效
换言之:
class Person
{
List<Pet> myPets;
float averageAge;
boolean isAgeValid = false;
float getAverageAge()
{
if(isAgeValid)
return averageAge;
else
...calculate age, save it in averageAge, set bool to true, and return derived float...
}
//all list operations should mark the bool false
void Add(Pet p)
{
myPets.Add(p);
isAgeValid=false;
}
}
班级人员
{
列出我的宠物;
浮动平均数;
布尔值isAgeValid=false;
float getAverageAge()
{
if(isAgeValid)
平均回报率;
其他的
…计算年龄,将其保存在averageAge中,将bool设置为true,然后返回派生的float。。。
}
//所有列表操作都应将bool标记为false
无效添加(Pet p)
{
添加(p);
isAgeValid=false;
}
}
更好的是,平均值可以缓存,而不是每次重新计算“从面向对象的角度来看,关于平均值的信息无论如何都不应该直接出现在Person对象中。”-我对此不太确定。通常在OOP中,一些代码希望请求某个类为其执行计算,而不必担心数据的内部或中间表示。我认为person.getPetsAverageAge()之类的方法是一种合适的方法,但这违反了单一责任原则。据我所知,Person类负责表示人的抽象概念。如果您还让它负责对相关类进行计算,那么您就给了它第二个责任。当然,除非一个人的唯一目的是进行这些计算,否则他不代表一个人。但是这个命名是非常误导的。更好的是,平均值可以缓存,而不是每次重新计算“从面向对象的角度来看,关于平均值的信息无论如何不应该直接出现在Person对象中。”-我不太确定这一点。通常在OOP中,一些代码希望请求某个类为其执行计算,而不必担心数据的内部或中间表示。我认为person.getPetsAverageAge()之类的方法是一种合适的方法,但这违反了单一责任原则。据我所知,Person类负责表示人的抽象概念。如果您还让它负责对相关类进行计算,那么您就给了它第二个责任。当然,除非一个人的唯一目的是进行这些计算,否则他不代表一个人。但是这个命名很容易引起误解。当宠物的内部状态/年龄更改为isAgeValid为false时,你也可以为宠物调用Person方法。将其标记为public(或者在设计级别更恰当地称为package)是可以的,因为在不适当的时间调用它不会损坏任何数据,它只会导致后续的额外计算。我真的希望将类A和类B正确地分开。这就是为什么我首先考虑将更新代码放在一个单独的类中。正确的分离可能是上面的答案,其中有一个类型为Pet的泛型集合的子类,这就增加了这个功能。当宠物的内部状态/年龄更改为isAgeValid为false时,你也可以为宠物调用Person方法。将其标记为public(或者在设计级别更合适地称为package)是可以的,因为在不适当的时间调用它不会损坏任何数据