简体   繁体   English

如何处理胖接口?

[英]How can I deal with a fat interface?

Say I have a big interface IShape of which Circle, Square, Triangle... inherit from.假设我有一个大接口 IShape,它继承自 Circle、Square、Triangle...。

IShape has become very big, and has functions dealing with unrelated topics: for example, many for dimensions calculation, others for moving and animations, others for colouring, etc. IShape 变得非常大,并且具有处理无关主题的功能:例如,许多用于尺寸计算,其他用于移动和动画,其他用于着色等。

This is against the Interface Segregation and Single Responsibility Principles, so I was trying to find the design pattern that better suits my case, but I am not sure about what is the best way for me to proceed.这违反了接口隔离和单一职责原则,所以我试图找到更适合我的情况的设计模式,但我不确定什么是我继续进行的最佳方式。

I was thinking in breaking IShape in smaller interfaces: IDimensions, IMovement, IColour... and then making Circle, Square and Triangle inherit from them.我正在考虑在更小的界面中打破 IShape:IDimensions、IMovement、IColour ......然后让 Circle、Square 和 Triangle 从它们继承。 This would solve the problem of the fat interface (although the implementations would still be very big).这将解决胖接口的问题(尽管实现仍然非常大)。

What is the approach I should follow?我应该遵循什么方法?

One approach is to keep the object (IShape) fairly "dumb" (keeping track of its internal state only, plus boilerplate access functions) and then add free-standing functions acting on it in more involved ways.一种方法是保持对象(IShape)相当“哑”(仅跟踪其内部状态,加上样板访问函数),然后添加以更复杂的方式作用于它的独立函数。 In some contexts it might be useful to integrate these functions into class interfaces of their own (particularly if the functionality can be grouped well and requires some internal state), but in my opinion and experience, there's nothing wrong with a library of free-standing functions acting on objects.在某些情况下,将这些函数集成到它们自己的类接口中可能很有用(特别是如果功能可以很好地分组并且需要一些内部状态),但根据我的观点和经验,独立库没有任何问题作用于对象的函数。 Note for example that large parts of the STL are made up by non-class functions.例如,请注意大部分 STL 是由非类函数组成的。

edit: Note that free-standing functions are basically automatically re-entrant (thread safe).编辑:请注意,独立功能基本上是自动可重入的(线程安全)。 With member functions, you have to pay more attention that the object state does not change, you might have to lock some sections, and so on.对于成员函数,您必须更加注意对象状态不会改变,您可能必须锁定某些部分,等等。

edit2: I generally try to favor composition of objects (object A "has an" object B) over inheritance (object A "is a type of" object B).编辑2:我通常尝试支持对象的组合(对象A“具有”对象B)而不是继承(对象A“是”对象B的一种)。 When you think about it, a square (which "is" a shape) might "have" a color, but it "is" not a color.当您考虑它时,正方形(“是”一种形状)可能“具有”一种颜色,但它“不是”一种颜色。 Also, think hard about on which level you compose objects: Does every Shape have a color and/or dimensions (in which case the Shape base class should have Color and Size/Polygon/Geometry/BoundingBox/... members), or do you want to keep the Shape interface more abstract in your code ecosystem (in which case concrete geometric shapes inherit from (abstract) Shape and additionally have further concrete properties, such as Size and Color)?此外,请认真考虑您在哪个级别构成对象:是否每个 Shape 都有颜色和/或尺寸(在这种情况下,Shape 基类应该具有 Color 和 Size/Polygon/Geometry/BoundingBox/... 成员),或者做你想在你的代码生态系统中保持 Shape 接口更加抽象(在这种情况下,具体的几何形状继承自(抽象)Shape,并且还具有进一步的具体属性,例如大小和颜色)? This (and the concrete implementation of eg Size/Geometry) depends mostly on what you want to do with your shape-like objects.这(以及例如大小/几何的具体实现)主要取决于您想要对形状类似的对象做什么。

I'm backing up the answer from Daniel and also would like to add a few tidbits.我支持丹尼尔的回答,也想补充一些花絮。

The third principle I believe is applicable is Separation of Concerns ( https://en.wikipedia.org/wiki/Separation_of_concerns ).我认为适用的第三个原则是关注点分离( https://en.wikipedia.org/wiki/Separation_of_concerns )。 It says everything and nothing and it also takes alot of time to get a mental hang on.它说明了一切,什么也没有,而且还需要很多时间才能保持精神状态。 I'm lacking much info about your application so I'm shooting in the dark, but, as an example of reasoning:我缺乏关于您的应用程序的很多信息,所以我在黑暗中拍摄,但是,作为推理的一个例子:

Why do you want to associate a circle and a square?为什么要将圆形和正方形关联起来? What are their comonality?他们的共同点是什么? Besides having lines that encircles a 2D area they don't have much in common.除了具有环绕 2D 区域的线之外,它们没有太多共同点。 A circle have a radius, a square have none.圆有半径,正方形没有。 In a square the angle between the legs are 90 degress - a circle has nothing of the sort.在正方形中,腿之间的角度是 90 度 - 圆形没有这种情况。 You can't describe the two using the very same set of explicitly, well defined variables.您无法使用完全相同的一组明确的、定义明确的变量来描述这两者。

So, why do you want to put them in the same basket?那么,为什么要把它们放在同一个篮子里呢? When you have the answer to that, or more probably the answer why not to have them in the same fat interface, I think you are on a good way of understanding your design.当你有答案,或者更可能的答案是为什么不让它们在同一个胖界面中时,我认为你正在理解你的设计的好方法。

Hope you find your way!希望你能找到自己的方式! /Nils /尼尔斯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM