Design Patterns 0 - Common Software Design Principles

Jan 23, 2021 00:00 · 790 words · 4 minute read DesignPatterns

Good design principles help you boost productivity!

As a data scientist, software design is a weak point of my skill sets. In industry, every model developed by a data scientist will eventually be put into production in an idea case. Having good software design mindset can help data scientists better connect with engineers and make the R&D to production transition smoother.

Here I summarized some good software design principles from the book Dive into Design Patterns by Alexander Shvets, which is very helpful to me for understanding design patterns in object-orient programming.

1. Features of Good Design

  • Code reuse: Reusing code can help reduce the development cost and time. When writing a function or class, keep code reuse in mind. It pays off in the end.
  • Extensibility: Change is a common thing in a programmer’s life. Making your library of software easily extend saves your time in the long run.

2. Good Design Principles

  • Encapsulate what varies: identify the aspects that varies and separate them from what stays the same. The main objective is to minimize the effect caused by changes. Encapsulation can be done on either a method level or a class level.
  • Program to an interface, not an implementation: Depend on abstractions, not on concrete classes. For example, when coding the relation between Company and individual employees such as Data Scientists (DS) and Software Engineers (SE), instead of connecting Company and DS/SE classes directly, write an Employee abstract class and connect Company with Employee class. This can help with the extensibility in the future. When set up collaboration between objects:
    • Determine what exactly one object needs from the other.
    • Describe these methods in a new interface or abstract class.
    • Make the class that is a dependency implement this interface.
    • Make the second class depend on this new interface rather than the concrete class.
  • Favor composition over inheritance: Inheritance is probably the most obvious and easy way of reusing code between classes. However, it also comes with caveats especially when you have tons of classes and changing anything is pretty hard. A subclass cannot reduce the interface of the superclass. When overriding methods, you need to make sure the new behavior is compatible with the pattern class.
    • Inheritance represents the “is a” relationship between classes.
    • Composition represents the “has a” relationship between classes.
  • SOLID principles
    • Single responsibility principle: A class should have just one reason to change. Try to make every class responsible for a single part of the functionality provided by the software. If a function becomes too complicated, please check whether it’s time to divide some classes into parts.
    • Open/Closed principle: Classes should be open for extension but closed for modification. This is for keeping existing code from breaking when adding new features.
    • Liskov substitution principle: The subclass should remain compatible with the superclass. When passing objects of the subclass in place of objects of superclass, it should not break the code.
    • Interface segregation principle: Make the interfaces narrow enough that client classes don’t have to implement behaviors they don’t need.
    • Dependency inversion principle: High-level classes shouldn’t depend on low-level classes. Both should depend on abstractions. Abstractions should depend on details.

3. UML Diagram

A UML(Unified Modeling Language) diagram is a diagram based on the UML with the purpose of visually representing a system. In software engineering, a class diagram in the Unified Modeling Language (UML) is a type of static structure diagram that describes the structure of a system by showing the system’s classes, their attributes, operations (or methods), and the relationships among objects. UML diagrams are typically used in object-oriented programming and system design.

Following is a typical UML diagram. A Person class has two public properties/methods name and age. The Student and Professor classes inherit the Person class with different additional public methods.

The arrows represent different relations as bellow:

  • Dependency exists between two elements if changes in one element may cause changes in the other.
  • Association represents a family of links for classes that are related.
  • Aggregation is a variant of the “has a” association relationship; aggregation is more specific than association. It is an association that represents a part-whole or part-of relationship.
  • Composition connects contained class(es) to the containing class. When attempting to represent real-world whole-part relationships, e.g. an engine is a part of a car. When the container is destroyed, the contents are also destroyed, e.g. a university and its departments. A Car has exactly one Carburetor, and a Carburetor is a part of one Car. Carburetors cannot exist as separate parts, detached from a specific car.

In a UML diagram, different signs are used to represent different access levels:

  • + means public
  • - means private
  • # means protected

Hope you find this useful as well!

Reference:

tweet Share

Related Articles