@@ -753,6 +753,78 @@ print(person.name_as_first_and_last) # => ["Ryan", "McDermott"]
753753##** Classes**
754754
755755###** Single Responsibility Principle (SRP)**
756+
757+ Robert C. Martin writes:
758+
759+ > A class should have only one reason to change.
760+
761+ "Reasons to change" are, in essence, the responsibilities managed by a class or
762+ function.
763+
764+ In the following example, we create an HTML element that represents a comment with
765+ the version of the document:
766+
767+ ** Bad**
768+ ``` python
769+ from importlibimport metadata
770+
771+
772+ class VersionCommentElement :
773+ """ An element that renders an HTML comment with the program's version number
774+ """
775+
776+ def get_version (self ) ->str :
777+ """ Get the package version"""
778+ return metadata.version(" pip" )
779+
780+ def render (self ) ->None :
781+ print (f ' <!-- Version: { self .get_version()} --> ' )
782+
783+
784+ VersionCommentElement().render()
785+ ```
786+ This class has two responsibilities:
787+
788+ - Retrieve the version number of the Python package
789+ - Render itself as an HTML element
790+
791+ Any change to one or the other carries the risk of impacting the other.
792+
793+ We can rewrite the class and decouple these responsibilities:
794+
795+ ** Good**
796+ ``` python
797+ from importlibimport metadata
798+
799+
800+ def get_version (pkg_name :str ) ->str :
801+ """ Retrieve the version of a given package"""
802+ return metadata.version(pkg_name)
803+
804+
805+ class VersionCommentElement :
806+ """ An element that renders an HTML comment with the program's version number
807+ """
808+
809+ def __init__ (self ,version :str ):
810+ self .version= version
811+
812+ def render (self ) ->None :
813+ print (f ' <!-- Version: { self .version} --> ' )
814+
815+
816+ VersionCommentElement(get_version(" pip" )).render()
817+ ```
818+
819+ The result is that the class only needs to take care of rendering itself. It
820+ receives the version text during instantiation and this text is generated by
821+ calling a separate function,` get_version() ` . Changing the class has no
822+ impact on the other, and vice-versa, as long as the contract between them does
823+ not change, i.e. the function provides a string and the class` __init__ ` method
824+ accepts a string.
825+
826+ As an added bonus, the` get_version() ` is now reusable elsewhere.
827+
756828###** Open/Closed Principle (OCP)**
757829###** Liskov Substitution Principle (LSP)**
758830###** Interface Segregation Principle (ISP)**