0

Consider a case, in which a class needs an attribute only in a very limited context. (For example, only during initialization, which is handled by a factory) I do not want to include such an attribute in the class, in order to keep it as simple as possible.

In the concrete example, I have a sorted list of tree nodes with given depth. Every node is direct child of the last node that has a smaller depth and comes before the child node itself. Once the tree is properly built and all parents contain links to their children, the depth is no longer required.

Here are the options I have considered in python:

  • Just including the attribute in the class (ugly)
  • Monkey patching the attribute in the factory method and removing it afterwards (uglier)
  • Using the following dataclass in the factory method:
@dataclass
class NodeAndDepth:
    depth: int
    node: Node
  • Using the following class, and than "casting" the objects into the simpler one:
class NodeWithDepth(Node):
    def __init__(self, depth, ...):
        ...

2 Answers2

6
  1. If an attribute is only needed for the time of a very specific operation (e.g. initialization), it is not really an attribute but a parameter or a local variable of that operation. Don’t bother.

  2. If the operation is complex to the point that it could be encapsulated in a class (e.g. a builder, factory, a strategy, or a visitor) then you could want to make it an attribute of that operation class. Two main reason can justify this choice: 1) the operation is decomposed into several simpler operations, each requiring access to this attribute; 2) the attribute is reused between successive invocation of the operation. But if there is no need, don’t do it: YAGNI.

  3. If there is a semantic link between the attribute and the class, i.e if independently of the operation the attribute means something relevant, you may want to keep it. It could save you time sooner or later. The depth of a tree is a perfect candidate, if you were able to easily keep it up-to-date. If not, go back to 1.

Christophe
  • 81,699
1

If the attribute is volatile and not always needed, look at how databases do this..

In databases, you implement occasional, loose relations between data by using junction table records, connecting records from one table with other records in another table.

In this case, you'd have a ClassInstances table with an index named ClassInstanceId, and you'll have a table Attributes with an AttributeId. You introduce new table named InstanceAttribute only containing the indexes you want to connect..

enter image description here

Advantages of this approach, also when it is used in memory: (1) you don't have to change your Class declaration to add Attributes.. (2) you can have an arbitrary number of attributes per instance and (3) you could store attribute sets only once, share them.

Goodies
  • 115