Skip to content

Architectural Notes

Thor Whalen edited this page Feb 27, 2023 · 2 revisions

Misc

In the Repository Design Pattern article, the author reflected on which methods to include in his DAO "Repository Pattern" abstraction, coming up pretty much with the same list as I, for similar reasons.

Tried and abandoned approaches

The convoluted (yet full of ideas) old way of doing local file persistence

Refer to local_files.py here: https://github.com/i2mint/py2store/blob/3260983a8ec4675485e0547cf4d6042ef562e466/py2store/persisters/local_files.py

Separating each CRD concern

https://github.com/i2mint/py2store/blob/3260983a8ec4675485e0547cf4d6042ef562e466/py2store/persisters/local_files.py#L190-L263

Here, I separated the read, write and delete concerns. My intent was to be able to keep the flexibility of composing them together as I wanted (R, RW, RWD, RD, WD, etc.). But as I went beyond RWD, adding __iter__, __len__ etc., and as I started building up the code, it seemed to convoluted, heavy, and in fact less DRY (though DRY was one of the intents).

Instead, the current architecture obliges the user to define all the necessary methods of a Persister: __getitem__, __setitem__, __delitem__, __iter__, the suggested way to handle flexibility being:

  • If an operation doesn't make sense (for example, writing to a dropbox readonly link) when making a Persister, the developer should define it, but raise an exception saying why it's not there.
  • If an operation is possible (for example writing to a file) but the developer or user wishes to disable it, again they can subclass the Persister or Store, and overwrite (with exception raising code) the methods they wish to disable.

Invisible kwargs

I originally was using verbose signatures, such as in https://github.com/i2mint/py2store/blob/3260983a8ec4675485e0547cf4d6042ef562e466/py2store/persisters/local_files.py#L271-L277

The reason was, I wanted to expose all the options in a readable manner (not use the obscure *args, **kwargs style that some libraries use). But it came to the expense of lots of code copy/pasting.

There must be a better way.

I've since developed some functools.wraps and inspect.signature based techniques to be able to do some of the stuff I'd like to do, but in the case of local file persisters, I've decided some of the options given by the open function are rarely used anyway, so I'll hide them behind the **open_kwargs curtain now.