jeudi 2 décembre 2021

Design Pattern question: removing overuse of boolean function parameters

It's been decades since I've brushed up on the gang-of-four. I've lately been getting a bad smell from some code, and am looking for recommendations on optimal design.

There exists a function that services an API POST by accepting a binary upload, performing various processing on it, and storing a file. Over time, as new requirements have emerged, some of the steps in that function have needed to be skipped, based on the type of binary being uploaded. Over time, the method signature has evolved like so:

First iteration:

public ResponseObject uploadThing(long user_id, long location_id, byte[] file_bytes)

Second iteration:

public ResponseObject uploadThing(long user_id, long location_id, byte[] file_bytes, boolean ignore_azure)

Third iteration:

public ResponseObject uploadThing(long user_id, long location_id, byte[] file_bytes, boolean ignore_azure, boolean ignore_aws)

Fourth iteration:

public ResponseObject uploadThing(long user_id, long location_id, byte[] file_bytes, boolean ignore_azure, boolean ignore_aws, boolean log_to_airtable)

The booleans correspond to newly added conditionals wrapping the related sections of the function. There are multiple pathways into this function, so every time a new boolean is added, all the calling code needs to be revisited. Also, the code becomes less and less self-documenting. Here's an example of it in one place:

ro = uploadThing(user_id, org_id, file_bytes, true, false, true)

If any of the boolean-dependent code is actually triggered, the order of execution is critical. Also there's no information contained in the other parameters that could be used to determine which sections of the uploadThing method to execute - it's purely based on where the particular calling code is.

Some of the things I don't like about this: the increasingly tight coupling between caller and callee, the increasing need to cover multiple spots in a refactor, and the increasing obfuscation of the method call's intended behavior at the point where it's being called. How would you restructure this?

Aucun commentaire:

Enregistrer un commentaire