Python合成

Python合成,python,oop,composition,Python,Oop,Composition,只是想提高我在Python中的OO使用,我对组合很好奇 例如,假设您有以下课程: Class Breakfast(object): __init__(self, eggs): self.eggs = eggs @property def yolk(self): return eggs.yolk @property def yolk_colour(self): return eggs.yolk.colour

只是想提高我在Python中的OO使用,我对组合很好奇

例如,假设您有以下课程:

Class Breakfast(object):
    __init__(self, eggs):
        self.eggs = eggs

    @property
    def yolk(self):
        return eggs.yolk

    @property
    def yolk_colour(self):
        return eggs.yolk.colour
        OR
        return.eggs.yolk_colour

Class Eggs(object):
    __init__(self, yolk):
        self.yolk = yolk

    @property
    def yolk_colour(self):
        return self.yolk.colour

Class Yolk(object):
    __init__(self, colour):
        self.colour = colour
并初始化它们

eggs = Eggs(Yolk("yellow"))
bkfast = Breakfast(eggs)
当你想要接触蛋黄时,是否最好将其按顺序连锁

bkfast.eggs.yolk
或者通过属性访问它

bkfast.yolk
第二个版本直接使用较少的链接,尽管仍然在幕后使用。而第一个向你展示了到底发生了什么。有没有更好的方法


编辑:我加入了蛋黄的一个属性,它有颜色。如果你想从早餐中获得这种颜色,那么最好是拥有一种称为鸡蛋属性的早餐属性,还是直接接触蛋黄本身?或者这不重要,因为它是幕后的吗?

在我看来,对于这个特定的示例,最好通过属性
bkfast.yolk
访问它,因为这样您就可以自由更改yolk的底层实现。

在我看来,对于这个特定的示例,最好通过属性
bkfast.yolk
访问它,因为这样您就可以自由地更改yolk的底层实现

对我来说,这意味着如果没有具体问题,你的例子就没有意义。如果你需要作曲,一定要作曲。如果你不需要,就不要。考虑一下你的界面的意义,让它简单明了

不管怎样,早餐的蛋黄是关于什么的?

来自

对我来说,这意味着如果没有具体问题,你的例子就没有意义。如果你需要作曲,一定要作曲。如果你不需要,就不要。考虑一下你的界面的意义,让它简单明了


无论如何,早餐的蛋黄是关于什么的?

人为设计的课程在某种程度上混淆了这个问题。这在某种程度上取决于您正在尝试做什么,或者具体地说取决于您正在使用的对象图是如何定义的。从
早餐
跳到
蛋黄
是不自然的……您不太可能直接跳到早餐集合的蛋黄子对象

在这种情况下,合同很可能是早餐将提供
鸡蛋
对象,因此您将返回该对象,然后在需要时从那里获取蛋黄(但这只涉及
鸡蛋
对象…
早餐
停止关心

如果出于某种原因,您确实希望始终如一地抓住核心,那么您应该使用委托。您永远不希望您的客户机代码比它必须或应该关心的更多(上面的Demeter定律),并且您永远不希望有任何事情,除了定义和管理的API泄漏到客户机代码之外

一个更合理的例子是假设你早餐吃不同形式的鸡蛋,所以它可能来自一个盘子,或者一个小的煮鸡蛋架,或者来自一个玻璃杯,“Rocky”在这种情况下,客户机代码仍然只需要鸡蛋,因此您需要使用委托,并从相应的盘子、架子或玻璃子容器中取出鸡蛋


归根结底,就是要定义您向客户机代码公开的内容,并确保接收对象处理和抽象了任何行李或实现细节。您总是希望根据您要交付的内容而不是来自何处来工作。

人为设计的类在某种程度上混淆了问题。这在某种程度上是错误的取决于您尝试执行的操作,或者具体地说,您正在使用的对象图是如何定义的。从
早餐
跳到
蛋黄
是不自然的……您不太可能直接跳到早餐聚合的蛋黄子对象

在这种情况下,合同很可能是早餐将提供
鸡蛋
对象,因此您将返回该对象,然后在需要时从那里获取蛋黄(但这只涉及
鸡蛋
对象…
早餐
停止关心

如果出于某种原因,您确实希望始终如一地抓住核心,那么您应该使用委托。您永远不希望您的客户机代码比它必须或应该关心的更多(上面的Demeter定律),并且您永远不希望有任何事情,除了定义和管理的API泄漏到客户机代码之外

一个更合理的例子是假设你早餐吃不同形式的鸡蛋,所以它可能来自一个盘子,或者一个小的煮鸡蛋架,或者来自一个玻璃杯,“Rocky”在这种情况下,客户机代码仍然只需要鸡蛋,因此您需要使用委托,并从相应的盘子、架子或玻璃子容器中取出鸡蛋


归根结底,就是要定义您向客户机代码公开的内容,并确保接收对象处理和抽象了所有的行李或实现细节。您总是希望根据交付的内容而不是来自何处来工作。

-使用后一个选项Python的Zen:Explicit比n隐式。简单比复杂好。你能在这里澄清一下Python的禅吗?对我来说,“显式比隐式好”倾向于第一种方法,因为你明确说明了蛋黄的来源。“简单比复杂”似乎支持第二种方法。@Stu:我认为“简单胜于复杂”!=“短胜于长”".用长名字或短名字来称呼某事物在复杂性上没有明显区别。@Mattwipple我在问题的另一部分添加了关于蛋黄颜色的内容。早餐如何返回颜色是重要的,还是对用户来说这仍然是一个单一的呼召,符合德米特定律r?-使用后一个选项Python的禅宗:显式优于隐式。简单优于复杂。你能在这里澄清一下Python的禅宗吗?对我来说,“显式优于隐式”倾向于第一种方法,因为你要明确说明蛋黄的来源。“简单优于复杂”
Explicit is better than implicit.
Simple is better than complex.