Questions tagged «composition»

14
“偏爱组成而不是继承”的概念从何而来?
在过去的几个月中,“偏爱继承而不是继承”的口号似乎无处不在,并成为编程社区中的某种模因。每次看到它,我都会有些迷惑。就像有人在说“青睐锤子”。以我的经验,组合和继承是具有不同用例的两个不同工具,并且将它们视为可互换,并且一个在本质上优于另一个是没有意义的。 另外,我从来没有看到过真正的解释,说明为什么继承不好而组成很好,这让我更加怀疑。是否应该只凭信心接受?Liskov替换和多态性具有众所周知的明显好处,而IMO构成了使用面向对象编程的全部要点,而且从来没有人解释为什么应该丢弃它们以利于组合。 有谁知道这个概念的来历,其背后的原理是什么?

5
为什么我应该更喜欢合成而不是继承?
我总是读到,与继承相比,组合是首选。一对不同类型的博客文章,例如,提倡使用超过组成继承,但我看不出多态性是如何实现的。 但是我有一种感觉,当人们说喜欢组合时,他们的意思是更喜欢组合和接口实现的组合。您将如何在没有继承的情况下实现多态? 这是我使用继承的具体示例。如何将其更改为使用合成,我将获得什么? Class Shape { string name; public: void getName(); virtual void draw()=0; } Class Circle: public Shape { void draw(/*draw circle*/); }

3
“构成超越继承”是否违反了“枯燥原则”?
例如,考虑我有一个可供其他类扩展的类: public class LoginPage { public String userId; public String session; public boolean checkSessionValid() { } } 和一些子类: public class HomePage extends LoginPage { } public class EditInfoPage extends LoginPage { } 实际上,子类没有任何方法可以覆盖,也不会以通用方式访问HomePage,即:我不会做类似的事情: for (int i = 0; i < loginPages.length; i++) { loginPages[i].doSomething(); } 我只想重用登录页面。但是根据https://stackoverflow.com/a/53354,我在这里更喜欢合成,因为我不需要LoginLog接口,所以在这里我不使用继承: public class HomePage { …

5
与定义一个方法可以调用相比,如何定义一个方法可以被覆盖更强的承诺?
来自:http : //www.artima.com/lejava/articles/designprinciples4.html 埃里希·伽玛(Erich Gamma):即使十年之后,我仍然认为这是真的。继承是改变行为的一种很酷的方法。但是我们知道它很脆弱,因为子类可以轻松地对调用其重写的方法的上下文进行假设。基类和子类之间存在紧密的耦合,因为隐式上下文将在其中调用我插入的子类代码。合成具有更好的属性。通过将一些较小的东西插入较大的对象中,可以减少耦合,而较大的对象仅将较小的对象回调。从API的角度来看,定义可以覆盖的方法比定义可以调用的方法要强。 我不明白他的意思。有人可以解释一下吗?

2
“不组成”是什么意思?
我看到很多文本,特别是函数式编程文本,声称某些CS概念“不构成”。例如:锁不组成,单子不组成。 我一直很难找到这句话的确切含义。当我想到组合时,我想到的是函数组合或对象聚合(如“在继承中偏爱组合”),但这似乎并不是人们在这里使用它的意义。 有人可以解释在上述两个示例(即锁和单子)这样的表达式中使用该短语时的含义吗?

8
“优先考虑组成而不是继承”-防御签名变更的唯一理由是吗?
此页面使用以下参数提倡在继承上进行组合(用我的措辞重新表述): 当我们使用继承时,超类方法签名的更改(尚未在子类中重写)会在许多地方引起其他更改。但是,当我们使用Composition时,所需的其他更改仅在单个位置:子类。 难道这真的是偏向于继承而不是继承的唯一理由吗?因为是这样的话,即使子类不更改实现(即在子类中放置虚拟替代),也可以通过强制采用提倡重写超类的所有方法的编码样式来轻松缓解此问题。我在这里想念什么吗?

2
如何避免在包装器中编写大量传递函数?
我有一个类,它包装了一个通用基本类型的另一个类。由于基本类型的接口很大,因此需要编写许多传递函数。我正在寻找避免这种情况的方法。 让我们举个例子: Car / \ Volvo VolvoWithTrailer 现在,我必须在VolvoWithTrailer的car接口中实现每个函数,并在包装​​好的Volvo对象上调用适当的函数,但GetMaxSpeed()可能会返回更低的值。基本上我将有很多功能,例如 int VolvoWithTrailer::GetNumSeats() { return mVolvo.GetNumSeats() } 解决此问题的一个明显方法是使VolvoWithTrailer成为Volvo的子类。 Car | Volvo | VolvoWithTrailer 但这似乎违反了主张组成优先于继承的原则。 我还要如何避免编写所有这些包装器(语言是C ++)?或者-如果那是您的职位-为什么我应该只写它们/只使用继承?有没有模板魔术可以帮助解决这个问题?

9
开发人员是否应该了解计算机硬件的内部运作方式?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 我不是在谈论内存的分配方式和内存管理(例如,您可以从C中学到的东西),而是在硬件方面,以及计算机硬件的每个组件在内部如何工作以及它们如何相互通信。 你们当中有多少人知道所有这些?

3
组成重于继承,但
我试图自学软件工程,遇到一些使我感到困惑的冲突信息。 我一直在学习OOP,以及什么是抽象类/接口以及如何使用它们,但是随后我读到,应该“偏重于继承而不是继承”。我知道组合是指一个类组成/创建另一个类的对象以利用/与该新对象的功能交互。 所以我的问题是...我应该不使用抽象类和接口吗?是否不创建抽象类并在具体类中扩展/继承该抽象类的功能,而是仅编写新对象以使用其他类的功能? 或者,我应该使用组合并从抽象类继承吗?两者结合使用?如果是这样,您能否提供一些示例,说明其工作方式及其好处? 因为我最熟悉PHP,所以在继续使用其他语言并转移我新获得的SE技能之前,我正在使用它来提高OOP / SE技能,因此,使用PHP的示例非常受赞赏。

4
手动进行依赖注入是否可以更好地替代组成和多态性?
首先,我是入门级程序员;实际上,我正在整个夏季完成AS学位,并完成了最终的顶峰项目。在我的新工作中,当我没有什么项目要做(他们正在等待团队中有更多新员工的到来)时,我在等待的过程中会得到一些可供阅读和学习的书籍-一些教科书,其他与其说是“代码完成”,不如说是。看完这些书之后,我转向互联网学习尽可能多的知识,并开始学习SOLID和DI(我们谈论了Liskov的替代原理,但没有其他SOLID想法)。因此,据我所知,我坐下来做得更好,并且开始编写一些代码以手工使用DI(开发计算机上没有DI框架)。 正如我所做的那样,我发现它感觉很熟悉……而且似乎很像我过去使用多态抽象类的组合所做的工作。我在这里想念大图吗?关于DI(至少是手工),还有其他一些东西吗?我了解在某些DI框架的代码中不包含配置的可能性,这些优点在无需重新编译的情况下就具有很大的好处,但是在手工操作时,我不确定它是否与上述内容有所不同...对此有一些了解将非常有帮助!


5
在这种情况下,我应该选择组合还是继承?
考虑一个接口: interface IWaveGenerator { SoundWave GenerateWave(double frequency, double lengthInSeconds); } 此接口由许多类实现,这些类生成不同形状的波(例如SineWaveGenerator和SquareWaveGenerator)。 我想实现一个SoundWave基于音乐数据而不是原始声音数据生成类的类。它会收到音符的名称和以拍子(不是秒)为单位的长度,并在内部使用该IWaveGenerator功能来创建一个音符SoundWave。 问题是,应该NoteGenerator包含IWaveGenerator还是应该从IWaveGenerator实现中继承? 由于两个原因,我倾向于合成: 1 -它让我注入任何IWaveGenerator的NoteGenerator动态。另外,我只需要一个NoteGenerator类,而不是SineNoteGenerator,SquareNoteGenerator等等。 2-无需NoteGenerator公开由定义的较低级接口IWaveGenerator。 但是,我发布此问题是为了听取对此的其他意见,也许是我没有想到的要点。 顺便说一句:我会说NoteGenerator 从概念上讲是an,IWaveGenerator因为它生成SoundWaves。

4
减少类中通过组合实现接口的样板
我有一个类:A这是一个综合了一些更小的类,的B,C和D。 B,C和D实现接口IB,IC和ID分别。 由于A支持的所有功能B,C并且D,A器具IB,IC并ID为好,但不幸的是这导致了大量的重路由在执行A 像这样: interface IB { int Foo {get;} } public class B : IB { public int Foo {get {return 5;}} } interface IC { void Bar(); } public class C : IC { public void Bar() { } } interface ID { string Bash{get; set;} } public …

1
是否存在使用弱引用而不是简单组合更好的情况?
虽然Java文档指定,即弱引用主要用于映射进行规范化,你会发现很多,很多,很多人在互联网上声称,该WeakHashMap中是完美的在其一生中存储的对象元数据。但是,没有人愿意做一个易于理解和适当的例子。 使用WeakHashMap向对象添加一些属性或存储元数据的声音对我来说,就像一个基于将要使用该死的东西的意愿的任意决定。换句话说-一个不好的设计。我了解,在某些情况下继承可能不可用(最终类,接口),但是组合又如何呢?我想不出一个例子,其中组合不是一种选择。当然,这是一个更好的选择,因为它依赖于公认的原则,而不是“语言怪癖”。 那么,有没有一种情况,使用弱引用而不是简单的组合会更好?如果没有,为什么互联网上的每个人似乎都会出错?

9
棋类的继承与组成
快速搜索此堆栈交换显示,通常认为合成比继承更灵活,但与往常一样,它取决于项目等,并且有时继承是更好的选择。我想制作一个3D象棋游戏,其中每个棋子都有一个网格,可能有不同的动画等等。在这个具体的例子中,似乎您可以为两种方法都辩护,我错了吗? 继承看起来像这样(使用适当的构造函数等) class BasePiece { virtual Squares GetValidMoveSquares() = 0; Mesh* mesh; // Other fields } class Pawn : public BasePiece { Squares GetValidMoveSquares() override; } 当然遵循“是”原则,而构图看起来像这样 class MovementComponent { virtual Squares GetValidMoveSquares() = 0; } class PawnMovementComponent { Squares GetValidMoveSquares() override; } enum class Type { PAWN, BISHOP, //etc …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.