SOLID Principles for Designers

Jose López Gonzálvez
5 min readAug 7, 2024

--

Este artículo también está disponible en español 🇪🇸

In recent years, we have witnessed an increasing convergence between the worlds of design and development. The fact is that until not too long ago, the term “branch” for the average designer referred to a hearty and tasty meal. Fortunately, we designers have adopted some methods and concepts traditionally related to the development field into our workflow, which not only enhances efficiency but also facilitates smoother collaboration with developers.

In this context of convergence, I wanted to write this article to explore how SOLID principles, originally conceived by Robert C. Martin at the beginning of this century as guidelines for quality software development, could provide a methodological framework for designing components of a design system, improving its robustness and scalability. Regardless of the contribution model, it’s crucial for the involved designers to fully understand these concepts. This will enhance communication and collaboration across disciplines and teams.

It’s important to note that this is a very personal perspective based on my experience as a designer, a humble proposal for approaching such a complex and fascinating topic that is very open to different interpretations. With this in mind, let’s explore the SOLID principles and their application in designing components of a Design System.

S — Single Responsibility Principle

This spoon has a focused and specialized design to perform a specific task. It’s not responsible for the temperature or the taste of the food.

The principle is defined as:

“A class should have only one reason to change”

We can interpret this as:

“A component should have a single purpose”

This principle invites us to create very focused and specialized components within our Design System, reducing unnecessary complexities. This greatly facilitates the maintenance and scalability of the components. For example, an inputText component should handle how its different states are displayed, but the form validation logic is not its responsibility. The best practice here is to atomize the components. If you need to create a complex component with multiple behaviors and actions, consider composing it from smaller pieces.

O — Open/Closed Principle

This ladder can extend to fit various heights and inclinations without needing structural modification.

This principle states:

“Software entities should be open for extension, but closed for modification.”

It could be adapted as:

“components should allow configuration without altering their structure.”

In context, this translates to designing components that make use of variants and have their customizable properties parameterized through props, thus allowing them to extend their use cases. This not only improves robustness but also facilitates the implementation and maintenance of the design system.

For example, a well-designed button component should be able to adapt to different styles, sizes, or states through its props, without hardcoding modifications or creating a new component for each variation.

Although using props is common in modern design systems, I find it interesting to highlight the flexibility and customization power that Newskit offers with them.

L — Liskov Substitution Principle

These fork and chopsticks can be used interchangeably, maintaining the functionality of bringing food to the mouth.

This principle says:

“Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it”

In component design, we could understand it as:

“Component’s variants must be able to be replaced with each other without affecting functionality”

This principle pushes us to ensure the consistency of component variants by setting limits on property parameterization. This facilitates maintenance and integration in various contexts.

For example, a button component with primary, secondary, and tertiary variants should allow an instance of the button, whether secondary or tertiary, to replace an instance of primary without affecting the UI functionality. This implies that all buttons must have the same configurable parameters and behave consistently when clicked.

If an additional feature is needed in a variant, we need to consider whether it can be implemented so that it’s available in all variants, or if it would be better to create a new and separate component.

I — Interface Segregation Principle

The bento box is modular and can contain different pieces of food.

For development, this principle states:

“Clients should not be forced to depend upon interfaces that they do not use”

In context and with a bit of creativity, it would be:

“Create modular components capable of adapting to more specific needs.”

This principle guides us towards decoupling and modularization of components. Instead of a monolithic component with multiple functionalities, it’s preferable to design components that can contain different smaller and specific pieces, combining them as needed. This increases the flexibility of components and greatly reduces the complexity of their maintenance.

Using customizable content slots in components is an excellent way to apply this principle. For example, instead of creating one or several card components with all possible internal variations, we should design a base card with slots for its header, content, and footer.

D — Dependency Inversion Principle

The adjustable wrench can fit different types of nuts and bolts, while the non-adjustable one is limited to a specific size.

El último de los principios es:

“Depend upon abstractions, not concretes”

This case does not need interpretation.

This principle leads us towards creating more versatile and reusable components. In a Design System, this means designing components that are abstract enough to function in various contexts, without being tied to a specific implementation or overly specific use case.

For example, when designing a card component, instead of creating a multitude of independent components or specific variants like sneakersCard or featuredOfferCard, it’s better to create a more generic productCard component that can adapt to different types of content, allowing the component to be used in multiple scenarios without needing modification.

As you can see, the key to these principles lies in maintaining focus at all times on modularity, flexibility, and coherence when designing components.

Their adoption not only improves the structure of our components but also fosters better communication and understanding between designers and developers. By using a common language and shared principles, we can create a more integrated and efficient workflow.

It’s important to remember that these principles should be understood as guidelines, not inflexible rules. The practical application of SOLID in designing components of a Design System can vary according to the specific needs of each project and team.

I’m sure you’re already applying one or more of these principles when designing components, and if not, I encourage you to consider using this methodological framework to help build a more robust and scalable Design System.

In any case, I’d love to hear opinions on the application of these principles in the design of components within a Design System. I encourage you to share your ideas and experiences in the comments.

--

--

Jose López Gonzálvez
Jose López Gonzálvez

Written by Jose López Gonzálvez

Product Designer & Design Systems Expert. With 20+ years turning ideas and business opportunities into valuable, user-friendly, and desirable experiences.