Como Implementar Design Patterns em TypeScript: Prototype

Amir Elemam
3 min readOct 22, 2023

--

O que é o Design Pattern Prototype?

O padrão de design Protótipo é um dos padrões de design criacional, que envolve a criação de objetos com base em um modelo de um objeto existente por meio de clonagem. Em vez de criar uma nova instância de um objeto do zero e configurá-lo, o padrão de protótipo permite copiar um objeto existente e possivelmente personalizá-lo.

Objetivo:
Especifica os tipos de objetos a serem criados usando uma instância prototípica e crie novos objetos copiando esse protótipo.

Aplicabilidade:

  • Quando as classes a serem instanciadas são especificadas em tempo de execução, por exemplo, por carregamento dinâmico.
  • Evitar a construção de uma hierarquia de classes de fábricas paralela à hierarquia de classes de produtos.
  • Quando as instâncias de uma classe podem ter uma das poucas combinações diferentes de estado.

Vantagens:

  • Subclasses reduzidas: O padrão de protótipo ajuda a reduzir o número de classes nomeadas que o sistema precisa, permitindo clonar um protótipo em vez de chamar um método de fábrica.
  • Configuração dinâmica de uma aplicação que usa classes: Através do uso de protótipos, é possível instanciar e configurar objetos dinamicamente.
  • Performance: Em cenários em que criar uma instância totalmente nova é mais caro do que copiar uma existente, usar o protótipo pode ser mais eficiente.

Desvantagens:

  • A cópia profunda de objetos pode ser complexa, especialmente se as referências internas do objeto levarem a estruturas cíclicas.
  • Nem todos os objetos podem ser clonados facilmente, dependendo de suas restrições de encapsulamento e estado interno.

Como implementar Prototype?

Vamos considerar um exemplo real onde o padrão de design Prototype pode ser útil: gerenciar formas gráficas em um aplicativo de desenho.
Imagine que você está criando um aplicativo de desenho e os usuários podem colocar formas como círculos, quadrados e linhas em uma tela.

Depois que uma forma é adicionada, os usuários podem querer criar duplicatas dessa forma com as mesmas propriedades, mas movê-las ou ajustá-las individualmente.

abstract class Shape {
x: number;
y: number;
color: string;

constructor(source?: Shape) {
if (source) {
this.x = source.x;
this.y = source.y;
this.color = source.color;
}
}

abstract clone(): Shape;
}

class Circle extends Shape {
radius: number;

constructor(source?: Circle) {
super(source);
this.radius = source ? source.radius : 0;
}

clone(): Circle {
return new Circle(this);
}
}

class Rectangle extends Shape {
width: number;
height: number;

constructor(source?: Rectangle) {
super(source);
this.width = source ? source.width : 0;
this.height = source ? source.height : 0;
}

clone(): Rectangle {
return new Rectangle(this);
}
}

Agora vamos usar estas classes:

// Cria uma instância de Circle
let circle: Circle = new Circle();
circle.x = 10;
circle.y = 10;
circle.radius = 20;
circle.color = "red";

// Clona circle
let anotherCircle: Circle = circle.clone();
anotherCircle.x = 20; // move the cloned circle to a different position

// Cria uma instância de Rectangle
let rectangle: Rectangle = new Rectangle();
rectangle.x = 5;
rectangle.y = 5;
rectangle.width = 50;
rectangle.height = 30;
rectangle.color = "blue";

// Clona rectangle
let anotherRectangle: Rectangle = rectangle.clone();
anotherRectangle.width = 60; // change the width of the cloned rectangle

// Neste momento, we temos as formas original e clonada com algumas propriedades compartilhadas e algumas alteradas.

Neste exemplo, o padrão Prototype permite a criação fácil e eficiente de novos objetos de forma que carregam as propriedades das formas existentes, mas podem ser modificados individualmente.

Ao considerar o padrão de protótipo, é essencial avaliar os prós e os contras no contexto dos requisitos e complexidades específicos da aplicação em questão.

--

--