Tomáš Peterka

std::blogout


Project maintained by katomaso Hosted on GitHub Pages — Theme by mattgraham

Constructors

Disclaimer: I personally think that classes are being overused. A simple function is more testable and elegant. Classes should be used only when you need to keep state between two function calls.

Constructor

Why?

Because of testability. For every class you are going to test you need to know in what state it is. If a constructor was running some functions in background you are not the one in control. That will lead to potentially different class state with the same construct parameters.

I need runtime information because it defines state of class

No you do not. Runtime information should be obtained in runtime by a function/method. Class state never depends on external runtime states.

How do I distinguish class-state and runtime attribute?

The rule of thumb for me is: If you have used an attribute only once (or in one method) then it is a runtime information.

When you put runtime information into attributes you will make your app hard to extend and messy.

Example

class Computer:
    def __init__(self, ncpu, ram):
        # simple asignment is ok
        self.ram = ram

        # construct private attribute from a public one
        # I prefer to save the public one too in case of serialization/deserialization
        self.ncpu = ncpu
        self._cpu_list = [CPU(n) for n in range(ncpu)]

        # this should never happen
        # do NOT perform any actions in constructor
        self.constraintRAM(ram)

When you put all runtime information into attributes

class Computer:

    def __init__(self,
                 software_root,
                 instance_root,
                 master_url,
                 computer_id,
                 buildout,
                 logger,
                 maximum_periodicity=86400,
                 key_file=None,
                 cert_file=None,
                 signature_private_key_file=None,
                 signature_certificate_list=None,
                 download_binary_cache_url=None,
                 upload_binary_cache_url=None,
                 download_from_binary_cache_url_blacklist=None,
                 upload_to_binary_cache_url_blacklist=None,
                 upload_cache_url=None,
                 download_binary_dir_url=None,
                 upload_binary_dir_url=None,
                 upload_dir_url=None,
                 master_ca_file=None,
                 certificate_repository_path=None,
                 promise_timeout=3,
                 shacache_ca_file=None,
                 shacache_cert_file=None,
                 shacache_key_file=None,
                 shadir_ca_file=None,
                 shadir_cert_file=None,
                 shadir_key_file=None,
                 forbid_supervisord_automatic_launch=False,
                 develop=False,
                 software_release_filter_list=None,
                 computer_partition_filter_list=None,
                 software_min_free_space=None,
                 instance_min_free_space=None,
                 instance_storage_home=None,
                 ipv4_global_network=None,
                 firewall_conf={},
                 ):