Skip to content

Instantly share code, notes, and snippets.

@brandon-braner
Created October 31, 2023 20:40
Show Gist options
  • Save brandon-braner/a67596a2cd390e023377956aa0864007 to your computer and use it in GitHub Desktop.
Save brandon-braner/a67596a2cd390e023377956aa0864007 to your computer and use it in GitHub Desktop.
Inheritance vs Composition

Composition vs Inheritance

Inheritance

Inheritance is the process by which one class takes on the attributes and methods of another. Newly formed classes are called child classes, and the classes that child classes are derived from are called parent classes.

This is a is-a relationship. The child class is a type of the parent class.

from abc import ABC, abstractmethod


class AbstractClass(ABC):

    @abstractmethod
    def do_something(self):
        pass


class ConcreteClass(AbstractClass):

    def do_something(self):
        print("ConcreteClass.do_something")

The Concreate(child class) needs to implement the abstract method of the Abstract(parent class).

This works very well for dependency injection and strategy patterns. The ability to switch in place a different implementation of the parent class.

In the example below we can switch out the implementations of ConcreteClass and ConcreteClass2 without changing the code that uses the class.

from abc import ABC, abstractmethod


class AbstractClass(ABC):

    @abstractmethod
    def do_something(self):
        pass


class ConcreteClass(AbstractClass):

    def do_something(self):
        print("ConcreteClass.do_something")

class ConcreteClass2(AbstractClass):

    def do_something(self):
        print("ConcreteClass.do_something")

Composition

Composition is the process of combining two or more distinct entities into a new whole, you "compose" a class.

This is a has-a relationship. You pass in the things the class needs to do its job.

class GCPAgreementBlob():
    
        def __init__(self, gcp_client):
            self.gcp_client = gcp_client
    
        def save(self):
            self.gcp_client.save_to_blob())
    ```


class DBAgreementSigned():
    
        def __init__(self, db_client):
            self.db_client = db_client
    
        def save(self):
            self.db_client.save_to_db())

class SalesforceAgreementSigned():
    
        def __init__(self, salesforce_client):
            self.salesforce_client = salesforce_client
    
        def save(self):
            self.salesforce_client.save_to_salesforce())


class DocusignSecondary():
        
            def __init__(self, blob_client: GCPAgreementBlob, db_client: DBAgreementSigned, salesforce_client: SalesforceAgreementSigned):
                self.blob_client = blob_client
                self.db_client = db_client
                self.salesforce_client = salesforce_client
        
            def save(self, config: Dict):
                self.blob_client.save()
                self.db_client.save()
                self.salesforce_client.save()


class APIKeySecondary():
        
            def __init__(self, db_client: DBAgreementSigned, salesforce_client: SalesforceAgreementSigned):
                self.db_client = db_client
                self.salesforce_client = salesforce_client
        
            def save(self):
                self.db_client.save()
                self.salesforce_client.save()

class ROWriter(DocusignSecondary):
        
            def __init__(self, config: Dict, blob_client: GCPAgreementBlob, db_client: DBAgreementSigned, salesforce_client: SalesforceAgreementSigned):
                self.config = config;
                super().__init__(blob_client, db_client, salesforce_client)
        
            def save(self):
                super().save(self.config)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment