added 376 characters in body
Source Link
Christophe
  • 71.6k
  • 10
  • 111
  • 178

A key principle of software engineering is separation of concerns. This leads to separate independent things, and group strongly related things. Your question seems to be about that.

Your questionwording unfortunately leaves a couple of open issues regarding the context. Moreover its terminology could mislead. So, let's first agree that classes and objects are meant to couple and encapsulate data and processing. So "coupling data and logic" is not a realan issue but simply a fact of object oriented life. Hence, and what you call "your use of the word "data" is to be understood inas a coloquialcolloquial way but that it's in realityto refer about the information held invalue of objects (which could be of basic types, or of a more complex class composing several types).

So ifIf we ignore the ambiguous wording youwe then have the following main options:

  • Case 1: The complex computation belongs to the behaviorcompletely belongs to the responsibility of the class on which it is performed: you may. You could then perfectly store the result of the computation in the class. In fact, this is even the foundation of memoization.

    Example: TheThe objects of a class Polygon are made of a sequence of many PointsPoint. The calculation of the Polygon's surface could then beis a complex calculation that needs to identify a lot of triangles, and sum up the surface of all these triangles. THeThe calculation of the surface is probably a responsibility of the Polygon. Other classes may access the results using the method calculateSurface() which might store internally in private properties the results to reuse them in subsequent calls and avoid to recalculate everytime.

  • Case 2: The complex computation is independentcomputation is independent of the object on which it is performed, but the result makes only sense in the context of the computation: you'd. You'd prefer to create a separate object for the independent computation with its results. This decouples the algorithm and theits results, from the input class.

    Example: a genericgeneral-purpose statistical algorithm such as a linear regression can require a time-consuming computations. You may want to use this algorithm on the points of the polygon. You'd then usetherefore design a generic LinearRegression class, in which you inject an iterator that will access the input points. THis This ensures that the same algorithm could be reused also for real time-time quotations on the stock market. You'd probably use an adapteradapter that extracts the points from the polygon. The results would then be stored in `LinearRegression. This approach is also useful if it's not about one algorithm but a family of algorithms sharing some intermediary computations.

  • Case 3: Only the resultresult of the complex computation matters, and it has a life on its own: regardlesslife on its own. THen, regardless of how you'd implement the computation, a result object wouldshould be created.

    Example: you have a picture the input objects are pictures of a VTC camera as input object. You then have an A complex image processing AI algorithm that extracts a set of polygon of the picture, that. Each polygon corresponds to a human face identified in the picture. The polygon ispolygons produced are then used independently of the original image, which could even be discarded, while the polygon is usedfor example to find a match in a face-recognition database, or to compare faces identified accross several images.

So the most suitable approach depends heavily on the context, and especially how much the results are bound to the input or the algoirthm itself.

A key principle of software engineering is separation of concerns. This leads to separate independent things, and group strongly related things.

Your question unfortunately leaves a couple of open issues regarding the context. Moreover its terminology could mislead. So, let's first agree that classes and objects are meant to couple and encapsulate data and processing. So "coupling data and logic" is not a real issue but a fact of object oriented life, and what you call "data" is to be understood in a coloquial way but that it's in reality about information held in objects (which could be of basic types, or of a more complex class composing several types).

So if we ignore the ambiguous wording you have the following main options:

  • The complex computation belongs to the behavior of the class on which it is performed: you may store the result of the computation in the class. In fact, this is even the foundation of memoization.

    Example: The objects of a class Polygon are made of a sequence of many Points. The calculation of the Polygon's surface could then be a complex calculation that needs to identify a lot of triangles, and sum up the surface of all these triangles. THe calculation of the surface is probably a responsibility of the Polygon. Other classes access the results using the method calculateSurface() which might store internally in private properties the results to reuse them in subsequent calls.

  • The complex computation is independent of the object on which it is performed, but the result makes only sense in the context of the computation: you'd prefer to create a separate object for the independent computation with its results. This decouples the algorithm and the results, from the input.

    Example: a generic statistical algorithm such as a linear regression can require a time-consuming computations. You may want to use this algorithm on the points of the polygon. You'd then use a generic LinearRegression class, in which you inject an iterator that will access the input points. THis ensures that the same algorithm could be reused also for real time quotations on the stock market. You'd probably use an adapter that extracts the points from the polygon. The results would then be stored in `LinearRegression. This approach is also useful if it's not about one algorithm but a family of algorithms sharing some intermediary computations.

  • Only the result of the complex computation matters, and it has a life on its own: regardless how you'd implement the computation, a result object would be created.

    Example: you have a picture of a VTC camera as input object. You then have an image processing AI algorithm that extracts a polygon of the picture, that corresponds to a face identified in the picture. The polygon is then used independently of the original image which could even be discarded, while the polygon is used to find a match in a face-recognition database.

So the most suitable approach depends heavily on the context.

A key principle of software engineering is separation of concerns. This leads to separate independent things, and group strongly related things. Your question seems to be about that.

Your wording unfortunately leaves a couple of open issues regarding the context. Moreover its terminology could mislead. So, let's first agree that classes and objects are meant to couple and encapsulate data and processing. So "coupling data and logic" is not an issue but simply a fact of object oriented life. Hence, what your use of the word "data" is to be understood as a colloquial way to refer about the information value of objects (which could be of basic types, or of a more complex class composing several types).

If we ignore the ambiguous wording we then have the following main options:

  • Case 1: The complex computation completely belongs to the responsibility of the class on which it is performed. You could then perfectly store the result of the computation in the class. In fact, this is the foundation of memoization.

    Example: The objects of a class Polygon are made of a sequence of many Point. The calculation of the Polygon's surface is a complex calculation that needs to identify a lot of triangles, and sum up the surface of all these triangles. The calculation of the surface is probably a responsibility of the Polygon. Other classes may access the results using the method calculateSurface() which might store internally in private properties the results to reuse them in subsequent calls and avoid to recalculate everytime.

  • Case 2: The complex computation is independent of the object on which it is performed, but the result makes only sense in the context of the computation. You'd prefer to create a separate object for the independent computation with its results. This decouples the algorithm and its results, from the input class.

    Example: a general-purpose statistical algorithm such as a linear regression can require time-consuming computations. You may want to use this algorithm on the points of the polygon. You'd therefore design a generic LinearRegression class, in which you inject an iterator that will access the input points. This ensures that the same algorithm could be reused also for real-time quotations on the stock market. You'd probably use an adapter that extracts the points from the polygon. The results would then be stored in `LinearRegression. This approach is also useful if it's not about one algorithm but a family of algorithms sharing some intermediary computations.

  • Case 3: Only the result of the computation matters, and it has a life on its own. THen, regardless of how you'd implement the computation, a result object should be created.

    Example: the input objects are pictures of a VTC camera. A complex image processing AI algorithm extracts a set of polygon of the picture. Each polygon corresponds to a human face identified in the picture. The polygons produced are then used independently of the original image, which could even be discarded, for example to find a match in a face-recognition database, or to compare faces identified accross several images.

So the most suitable approach depends heavily on the context, and especially how much the results are bound to the input or the algoirthm itself.

Source Link
Christophe
  • 71.6k
  • 10
  • 111
  • 178

A key principle of software engineering is separation of concerns. This leads to separate independent things, and group strongly related things.

Your question unfortunately leaves a couple of open issues regarding the context. Moreover its terminology could mislead. So, let's first agree that classes and objects are meant to couple and encapsulate data and processing. So "coupling data and logic" is not a real issue but a fact of object oriented life, and what you call "data" is to be understood in a coloquial way but that it's in reality about information held in objects (which could be of basic types, or of a more complex class composing several types).

So if we ignore the ambiguous wording you have the following main options:

  • The complex computation belongs to the behavior of the class on which it is performed: you may store the result of the computation in the class. In fact, this is even the foundation of memoization.

    Example: The objects of a class Polygon are made of a sequence of many Points. The calculation of the Polygon's surface could then be a complex calculation that needs to identify a lot of triangles, and sum up the surface of all these triangles. THe calculation of the surface is probably a responsibility of the Polygon. Other classes access the results using the method calculateSurface() which might store internally in private properties the results to reuse them in subsequent calls.

  • The complex computation is independent of the object on which it is performed, but the result makes only sense in the context of the computation: you'd prefer to create a separate object for the independent computation with its results. This decouples the algorithm and the results, from the input.

    Example: a generic statistical algorithm such as a linear regression can require a time-consuming computations. You may want to use this algorithm on the points of the polygon. You'd then use a generic LinearRegression class, in which you inject an iterator that will access the input points. THis ensures that the same algorithm could be reused also for real time quotations on the stock market. You'd probably use an adapter that extracts the points from the polygon. The results would then be stored in `LinearRegression. This approach is also useful if it's not about one algorithm but a family of algorithms sharing some intermediary computations.

  • Only the result of the complex computation matters, and it has a life on its own: regardless how you'd implement the computation, a result object would be created.

    Example: you have a picture of a VTC camera as input object. You then have an image processing AI algorithm that extracts a polygon of the picture, that corresponds to a face identified in the picture. The polygon is then used independently of the original image which could even be discarded, while the polygon is used to find a match in a face-recognition database.

So the most suitable approach depends heavily on the context.