Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 寻找特定的设计模式_Design Patterns - Fatal编程技术网

Design patterns 寻找特定的设计模式

Design patterns 寻找特定的设计模式,design-patterns,Design Patterns,我在寻找一种描述特定情况的模式。也许有人知道些什么,可以给我一个提示 情况类型A的对象,1:n与类型B的对象关联。例如:一个人和他的所有宠物。宠物对象具有年龄数据成员。现在每个人都应该有一个宠物平均年龄的数据成员。我不希望保存和加载这些信息,而是希望在加载过程中计算这些信息(所有必要的信息都已经存在,所以有点多余,但我希望person对象中的信息) 问题那么如何以面向对象的方式实现这一点呢?是否有一种模式可以描述这种情况?我的第一个想法是让ComputedFieldsUpdater类接受一个宠物

我在寻找一种描述特定情况的模式。也许有人知道些什么,可以给我一个提示

情况类型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)是可以的,因为在不适当的时间调用它不会损坏任何数据