Pergunta

With relation to what's considered good OOP engineering principles, SOLID, DRY, KISS etc I am wondering whether to complete multiple tasks within one loop when easily done.

The problem is that this conflicts with some principles (SRP), but could also partially lean in favor of others (DRY, KISS).

A simple example would be

We have a array of image file paths and we want to complete 4 overall tasks per image

get size of image
resize the image
apply a watermark to the image
apply a border to the image

This could be achieved by using one for each loop on the array, and applying each function one after the other, or we could do this with four separate foreach loops, one for getting the size, one performing a resize and so on for the other tasks.

I am trying to adhere to these principles as much as possible to remove any bad habits and improve my coding skills.

Foi útil?

Solução

I beg to differ to what Creative Magic said. Unfortunately, our craft ain't easy and it is the same book that leads me to the conclusion that you should not do those 4 tasks within the loop itself, as that indeed violates the SRP.

Nevertheless, a simple change of your design satisfies all your desires: Let's start by implementing the four operations on their own, but for just one image (file). No loops, just the nitty gritty detail. Apart from maybe the first operation, all of these take an image as input, and return a slightly modified image - which as it just so happens, is the input to the next operation.

Mathematically, we call this a function composition. I don't know if there is a PHP library to directly support this, but nevertheless what you end up with is a composed function which needs to be applied to each of the images. So you have one loop with one statement and one responsibility.

As an example of how this may look like in another language, consider this pseudo code (similar to Google's guava library for Java) :

composedFunction = Functions.compose(applyBorderFunction, applyWaterMarkFunction,
                      resizeImageFunction, fileToImageFunction)
resultingImages = allMyImageFiles.transform(composedFunction)

If your language is not capable of expressing higher-order functions, then you can think of the transform call as one loop, and within that loop you may have to loop over your individual functions. Nevertheless, the responsibility of that resulting function is not implementing the individual transformations of your image, but simply applying those operations, whatever they may be.

So you end up with a clear separation of those two things: one, individual (and again properly separated) definitions of the operations you perform on your images, and two, the application of these operations.

As usual, you can find a design that is SOLID, and still DRY/KISS/whatever. It does take a lot of experience though to play around with different design options in your mind to find one that satisfies your needs.

Outras dicas

If your program is already working and a predictable result can be expected (in other words there are no bugs) you are left with two things to improve your code:

1) Optimisation - try to make your code run faster, take less memory, perform less operations etc. 2) Code readability - make your code more readable and understandable to reduce the WTF per Minute rating.

Funny thing, these two often contradict each other. To make the code more readable, you need to separate it into smaller classes, divide functions into smaller functions etc.
Optimization, on the other hand, would rather have many things stored locally to perform less calls to other classes, get some object nested in a parent object etc.

You example is interesting, because having 4 loops one after each other would make the code less readable, take more space (curly braces are often taking one line each) and perform less if the compiler wouldn't compile it as one loop anyway. In your case, PHP doesn't have a compiler, so it might actually affect performance, even if a little bit.

A simple advice would be: don't over engineer, strive to get your program working as first priority, make it readable and understandable and then optimize the bottle necks; sacrifice readability for optimization on performance critical code providing comments for that part.

A good book that helped many to understand how to be a better programmer: Clean Code: A Handbook of Agile Software Craftsmanship

Licenciado em: CC-BY-SA com atribuição
scroll top