dimanche 16 mai 2021

Is there a well known name for the "context manager" design pattern?

Python developers usually are well aware of Context Managers

with open('some_file', 'w') as opened_file:
    opened_file.write('Hola!')

with opening and closing files being the most prominent example.

However, there are numerous examples, where this pattern can be used (start/stop a timer, acquire release a lock, set a transaction to readonly for a nested scope, ...).

When talking to Java developers, I often propose to use the same pattern, known as try-with-resources statement.

try(BufferedWriter writer = new BufferedWriter(new FileWriter("some_file"))){
  writer.write("Hola!");
}

My problem is, that many Java developers don't know the "context manager" pattern and would never use this pattern for anything else but file handling.

In general the concept seems to exist in most modern languages in many variations:

Go's defer

f := createFile("some_file")
defer closeFile(f)
writeFile(f)

defer in Swift

do {
    let file = openFile()
    defer { closeFile(file) }
    file.write("Hola!")
}

And of course one can use destructors in languages supporting them (C++, Swift, ...):

// pseudo code for brevity
class ContextManager
  fileHandle;
  constructor(fileName)
    fileHandle = openFile
  write(string)
    fileHandle.write(string)
  destructor()
    fileHandle.close()

main()
  cm = ContexManager("some_file")
  cm.write("Hola!")
  // file closed on destruction of cm

The last pattern I often see is using blocks or lambdas (JavaScript, Java, Python, Swift, ...). E.g. in JavaScript one could write a context manager as

with("some_file", fileHandle => {
  fileHandle.write("Hola!")
})

My question is, if there is any well known design pattern I could refer to, to pitch context managers for timers, locks and other things to Java developers in the form of try-with-resources or lambdas?

Any thoughts (even "don't do this at all because...") or references to helpful articles are welcome.

Aucun commentaire:

Enregistrer un commentaire