DEV Community

FEConf
FEConf

Posted on

The Architecture of Web-Based Graphic Editors and 7 Design Patterns (Part 1)

*This article is a summary of the talk The Architecture of Web-Based Graphic Editors and 7 Design Patterns presented at FEConf 2023. The content of the presentation will be published in a two-part series. Part 1 will cover the basic architecture of a web-based graphic editor and the design patterns embedded within it. Part 2 will take a deeper dive into design patterns by actually implementing a graphic editor and addressing its problems. All images in this article are from the presentation slides of the same name and are not individually cited. The presentation slides can be downloaded from the FEConf 2023 website.

"The Architecture of Web-Based Graphic Editors and 7 Design Patterns" / Heungwoon Shim, Frontend Engineer at Naver, presented at FEConf 2023

Hello, I'm Heungwoon Shim, a frontend engineer at Naver working on platform development. In this article, we'll explore web-based graphic editors and design patterns.

At my previous and current companies, I've participated in five graphic editor development projects. These projects include a UI prototyping tool, a graphic editor framework, a bitmap image editor, and an annotation tool for generating machine learning training data. All five of these projects stem from a single root: GEF, a sub-project of Eclipse.

Image description

Eclipse GEF

GEF is a long-standing project that began in the early 2000s. It's integrated into Eclipse and is used to edit various Eclipse models with a GUI. At the time, our team adapted the GEF architecture for our projects, and in the process, we discovered that graphic editors incorporate a wide variety of design patterns. Although we've adapted and improved it to keep up with the evolving web ecosystem, the design patterns within it remain just as valid.

I wanted to share this to help others understand design patterns from a practical perspective. I hope this provides some ideas for web-based graphic editor projects and serves as a good starting point for those looking to apply design patterns in their work.

Here's what we'll cover in this article:

  1. The basic architecture of a web-based graphic editor
  2. The design patterns involved and what they solve

Revisiting Design Patterns

The word "pattern" can mean a template, a design, a sample, or a model. Derived from the French word patron, it refers to a recurring event or the form of an object. A simple example is the geometric repetition found in beehives or architecture.

Architecture and Patterns

From an engineering perspective, the concept of a pattern was first introduced in the book "A Pattern Language: Towns, Buildings, Construction" by architect Christopher Alexander. This book introduces 253 patterns for correctly arranging the elements that make up our living environment. Concepts like grids, topology, and networks, shown in the image below, might seem familiar, right?

Image description

The book "A Pattern Language"

Just as we find design patterns in code, the author observed recurring elements in spaces and buildings and contemplated their relationships with other elements. Did you know that the term 'portal,' which we often use, originates from architecture? If you look at the book "100 Ideas that Changed Architecture", you'll see many familiar terms.

Image description

The book "100 Ideas that Changed Architecture"

Module, layer, composition, style, platform, context—even their abstract meanings are very similar to how we use them. As you can see, architecture and programming have a lot in common. In this sense, if an architect is someone who designs physical spaces, then programmers, especially frontend developers, could be seen as architects who design mental spaces.

Programming and Patterns

The book below is the well-known "Design Patterns". It was published in 1994 by Erich Gamma, an architect of Eclipse and Visual Studio Code, along with Richard Helm, Ralph Johnson, and John Vlissides. This book widely popularized the concept of patterns in programming design.

Image description

The book "Design Patterns"

It introduces 23 patterns for properly designing software components, and its popularity led to the discovery and creation of many more patterns.

Design Patterns

So, what exactly is a design pattern? According to its definition on Wikipedia, it is "an accumulation of design expertise, named and organized into a reusable format." To put it more simply, it's a solution to a problem that occurs repeatedly in a specific context.

Design patterns are discovered through experience rather than invented. While DRY (Don't Repeat Yourself) is about reusing code, DP (Design Pattern) is about reusing experience.

Software design patterns can be broadly classified as follows:

  1. Architectural Patterns: MVC / Pub-Sub / DAO / DTO / Broker
  2. GoF (Gang of Four) Patterns: Creational / Structural / Behavioral
  3. Concurrency Patterns: Event-based / Scheduler / Reactor

There are many other design patterns besides these. In this article, we will introduce the seven patterns highlighted below.

Image description

The design patterns that will be covered in this article

Advantages of Design Patterns

  1. Good design simplifies implementation. Implementing without a design might seem fast at first, but inefficiency and complexity quickly increase over time.
  2. Enables effective communication. When explaining a system, using patterns allows for simple and precise communication. It reduces misunderstandings and helps everyone work more efficiently.
  3. Helps adhere to object-oriented principles.  The goal of the SOLID principles, which are the foundation of software quality, is to increase reusability, scalability, and maintainability. Since design patterns are fundamentally based on SOLID principles, mastering them helps you write flexible and extensible code.
  4. Fostering a design-first mindset. Design patterns become part of your mental model. When refactoring a large, problematic codebase, knowing design patterns helps you redesign the overall flow into a more effective structure.
  5. High-level view. A high-level view allows you to see the big picture. Design patterns are higher-level concepts than libraries or frameworks. Therefore, with an understanding of design patterns, you can more easily comprehend frameworks and code, and more clearly grasp the intent behind them.

How Design Patterns Solve Problems

We can think of how design patterns solve problems in three ways.

  1. Provide a way to make changes easily. The principles of design patterns are deeply related to software changes. Therefore, their core function is to make it easy to change parts of a system.
  2. Abstraction and delegation. To facilitate easy changes, they delegate the handling of variable parts to a specialized component. They isolate the changing parts of a system, abstract them, and delegate the work to specialized modules through an interface.
  3. Composition over inheritance. And they solve problems using composition rather than inheritance. The reason is that inheritance is determined at compile-time, while composition is determined at runtime, making it more flexible. For this reason, as shown in the image below, most of the GoF patterns are based on composition.

Image description

How design patterns solve problems

When is it good to use design patterns?

It's good to use them when you anticipate that a specific part of the system will change continuously. This is why design patterns are frequently used in frameworks. Frameworks provide a foundation, and development proceeds by swapping out the changeable parts. Also, if you find yourself constantly modifying if statements in your code, that's a good time to consider using one.

How should you use design patterns?

Simply follow the KISS principle. This principle was developed by the U.S. Navy: Keep It Small and Simple. In other words, it's best to use a design pattern when it simplifies the problem. However, there is no single correct answer. Since design patterns are "desirable experiences," you should apply them flexibly according to the situation.

The Design Pattern of Drawing

Now, let's explore the design patterns involved in the act of drawing. First, let's think about the editing task of drawing on a piece of paper. The process of drawing on paper follows these steps:

  1. You move the pencil.
  2. Graphite is transferred to the paper.
  3. The state of the paper changes.

So, what about the process of a program drawing a picture?

  1. You move an input device.
  2. An event is delivered.
  3. The state of the screen changes.

In essence, an editing task is the process of converting an event into a state change. Here, when the user provides an event, they expect the paper or monitor screen to change. This is the user's mental model.

Image description

Mental Model

Therefore, to summarize this process again, an editing task can be described as the process of converting a user's intent—their mental model—into a computer model through events.

Image description

The properties of an editing task

The MVC Pattern

There is an architecture designed for the process we just described: the MVC pattern, created in 1976 by Norwegian computer scientist Trygve Reenskaug at Xerox PARC. In this model, the View is responsible for the mental model, the Controller for the editing device, and the Model for the computer model.

Image description

MVC and the editing task

The Palo Alto Research Center is where the prototypes of many IT devices we enjoy today were developed. At the time, he was working on the team developing the Dynabook, which could be called a distant ancestor of the iPad. This team was led by Alan Kay, a pioneer in object-oriented programming and GUIs who also led the development of Smalltalk (the forerunner of object-oriented languages).

The team focused on improving GUIs to make them easier for users to use. In this process, Trygve Reenskaug had a realization: the user's mental model is different from the computer's way of processing information.

So, Trygve Reenskaug devised MVC as a structure for the process of converting the mental model into the computer model. The image below is a part of the paper Reenskaug wrote about MVC. The paper contains this passage: “This story is focused on the problem of bridging the gap between man and machine.”

Image description

The gap between man and machine - from the MVC paper

The Essence of MVC and What It Solves

He states, "The essential purpose of MVC is to bridge the gap between the user's mental model and the digital model that exists in the computer." "An ideal MVC solution supports the user's illusion of seeing and manipulating domain information directly." "This structure is also useful in situations where the user needs to see the same model from different perspectives simultaneously."

Image description

What MVC solves

Separation of Concerns in the MVC Pattern

The core of this pattern is to separate modules based on their roles—in other words, separation of concerns. By doing this, the MVC pattern can effectively translate the mental model into the computer model, which is why MVC and its derivatives are still used as the basis for various architectures even after 40 years.

Image description

MVC's separation of concerns

Modern MVC is often configured in slightly modified forms to fit a given situation, but a standard structure is shown in the diagram below. When the Controller receives a user event through the View, it creates and sends a command to modify the Model. Once the Model is modified, the View is updated based on the change. This MVC pattern is actually a composite pattern, combining several other patterns.

Image description

The structure of the modern MVC pattern

The Model is a classic example of a subject in the Observer pattern. The View and Controller listen for changes in the Model's state, but the Model should be unaware of their existence. Also, when a View or Controller is destroyed during its lifecycle, its subscription must be terminated.

Image description

Observer pattern in the Model

The GUI components that make up the View are often composed of nested structures like windows, panels, labels, and buttons. The Composite pattern is a pattern that treats such nested structures as a single object, thus abstracting the nesting.

Image description

Composite pattern in the View

The Strategy pattern is a typical pattern for the Controller. The View only passes events to the Controller and is not involved in changing the Model. How the Model is changed is determined by the Controller's logic. And this Controller, connected to the View, can be changed at runtime.

Image description

Strategy pattern in the Controller

We will take a closer look at these patterns in a later section.

Graphic Editor Architecture

Now, let's learn about the basic structure of a graphic editor. The diagram below shows the external structure of a graphic editor. There's a surrounding workbench, a menu and toolbar, and tools on the left. In the center is the canvas, and on the right, from top to bottom, are the Properties, Palette, History, and Layers panels. Finally, you can see the Status bar at the very bottom.

Image description

External structure of a graphic editor

In this section, we will explore design patterns by implementing the Tool, Canvas, and History areas, which are highlighted in orange in the diagram.

Internal Components

The internal structure varies by application, making it difficult to generalize, but I believe other applications likely have similar components. A graphic editor is internally composed of the following:

Image description

Internal components of a graphic editor

  • Model: The unique domain model that the editor can manipulate.
  • Graphic Viewer: The space where editing occurs based on graphic events.
  • Event Dispatcher: Converts low-level events from the web browser into high-level events for the editor.
  • Command Stack: Manages history by supporting undo and redo.
  • Root Part: The basic unit of editing is the "Part." Parts are responsible for performing editing actions.

Image description

RootPart of the internal components

  • Tool: Implements the tools from the external structure.
  • Action Registry: Handles keyboard shortcuts.
  • Request: An abstraction of an event.
  • EditPolicy: A micro-controller that executes the actual edits.

In the next article, we will provide a more detailed introduction to these internal components and explore how to apply design patterns by implementing a virtual graphic editor.

Top comments (0)