Trang chủHướng dẫnDecorator Design Pattern trong Java: Giải thích và ví dụ chi tiết
Java

Decorator Design Pattern trong Java: Giải thích và ví dụ chi tiết

CyStack blog 4 phút để đọc
CyStack blog16/07/2025
Locker Avatar

Bao Tran

Web Developer

Locker logo social
Reading Time: 4 minutes

Decorator Design Pattern (Mẫu thiết kế Decorator) trong Java được sử dụng để thay đổi chức năng của một đối tượng tại thời điểm chạy (runtime). Đồng thời, các instance khác của cùng một lớp sẽ không bị ảnh hưởng, vì vậy chỉ đối tượng cụ thể đó nhận được hành vi đã được thay đổi.

decorator design pattern trong Java

Decorator là một trong những mẫu thiết kế cấu trúc (structural design pattern) tương tự như Adapter Pattern, Bridge Pattern, Composite Pattern . Nó được triển khai bằng cách sử dụng lớp trừu tượng (abstract class) hoặc interface kết hợp với composition để triển khai.

Decorator design pattern

Chúng ta sử dụng inheritance hoặc composition để mở rộng hành vi của một đối tượng, nhưng điều này được thực hiện tại thời điểm biên dịch (compile time) và áp dụng cho tất cả các đối tượng của lớp đó. Chúng ta không thể thêm chức năng mới hoặc loại bỏ hành vi hiện có tại thời điểm chạy ,và đây chính là lúc Decorator pattern phát huy tác dụng.

Giả sử chúng ta muốn triển khai các loại xe khác nhau, ta có thể tạo một interface Car để định nghĩa phương thức assemble(), sau đó có thể xây dựng một xe cơ bản (Basic car), và tiếp tục mở rộng nó thành xe thể thao (Sports car) và xe sang trọng (Luxury car). Cấu trúc phân cấp triển khai (implementation hierarchy) sẽ giống như hình ảnh bên dưới.

decorator-examples

Nhưng nếu chúng ta muốn lấy một chiếc xe tại thời điểm chạycó cả hai tính năng của xe thể thao (sports car) và xe sang trọng (luxury car), thì việc triển khai sẽ trở nên phức tạp. Và nếu chúng ta muốn xác định thứ tự các tính năng được thêm vào, thì nó lại càng phức tạp hơn nữa. Bây giờ hãy tưởng tượng nếu chúng ta có mười loại xe khác nhau, thì logic triển khai sử dụng inheritance và composition sẽ trở nên khó kiểm soát và không thể quản lý được. Để giải quyết những tình huống lập trình như vậy, chúng ta áp dụng Decorator trong Java. Để triển khai mẫu thiết kế này, chúng ta cần các thành phần sau:

  1. Component Interface – Là interface hoặc lớp trừu tượng (abstract class) định nghĩa các phương thức sẽ được triển khai. Trong ví dụ của chúng ta, Car sẽ là component interface.
package com.journaldev.design.decorator;

public interface Car {

	public void assemble();
}
  1. Triển khai Component – Đây là cài đặt cơ bản của giao diện component. Chúng ta có thể sử dụng lớp BasicCar làm lớp triển khai component của mình.
package com.journaldev.design.decorator;

public class BasicCar implements Car {

	@Override
	public void assemble() {
		System.out.print("Basic Car.");
	}

}
  1. Decorator – Lớp Decorator triển khai giao diện component và có mối quan hệ HAS-A (có một) với giao diện component. Biến component cần phải được truy cập bởi các lớp decorator con, vì vậy chúng ta sẽ đặt biến này là protected.
package com.journaldev.design.decorator;

public class CarDecorator implements Car {

	protected Car car;
	
	public CarDecorator(Car c){
		this.car=c;
	}
	
	@Override
	public void assemble() {
		this.car.assemble();
	}

}
  1. Concrete Decorators – Các lớp này mở rộng chức năng của decorator cơ sởđiều chỉnh hành vi của component cho phù hợp. Chúng ta có thể có các lớp decorator cụ thể như LuxuryCar (xe sang trọng) và SportsCar (xe thể thao).
package com.journaldev.design.decorator;

public class SportsCar extends CarDecorator {

	public SportsCar(Car c) {
		super(c);
	}

	@Override
	public void assemble(){
		super.assemble();
		System.out.print(" Adding features of Sports Car.");
	}
}
package com.journaldev.design.decorator;

public class LuxuryCar extends CarDecorator {

	public LuxuryCar(Car c) {
		super(c);
	}
	
	@Override
	public void assemble(){
		super.assemble();
		System.out.print(" Adding features of Luxury Car.");
	}
}

Decorator design pattern– Sơ đồ lớp

decorator-pattern

Chương trình kiểm thử Decorator design pattern

package com.journaldev.design.test;

import com.journaldev.design.decorator.BasicCar;
import com.journaldev.design.decorator.Car;
import com.journaldev.design.decorator.LuxuryCar;
import com.journaldev.design.decorator.SportsCar;

public class DecoratorPatternTest {

	public static void main(String[] args) {
		Car sportsCar = new SportsCar(new BasicCar());
		sportsCar.assemble();
		System.out.println("\\n*****");
		
		Car sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));
		sportsLuxuryCar.assemble();
	}

}

Lưu ý rằng chương trình client có thể tạo các loại đối tượng khác nhau tại runtime và chúng cũng có thể chỉ định thứ tự thực hiện. Kết quả đầu ra của chương trình kiểm thử trên là:

Basic Car. Adding features of Sports Car.
*****
Basic Car. Adding features of Luxury Car. Adding features of Sports Car.

Decorator design pattern – Những điểm quan trọng

  • Mẫu thiết kế Decorator rất hữu ích trong việc cung cấp khả năng thay đổi hành vi tại thời điểm chạy , do đó mang lại sự linh hoạt cao hơn. Nó cũng dễ bảo trì và mở rộng khi số lượng lựa chọn (chức năng) tăng lên.
  • Nhược điểm Decorator pattern là nó sử dụng nhiều đối tượng có kiểu tương tự nhau (các decorator), điều này có thể khiến cho cấu trúc chương trình trở nên phức tạp nếu không quản lý tốt.
  • Mẫu Decorator được sử dụng rất nhiều trong các lớp Java IO, chẳng hạn như FileReader, BufferedReader, v.v.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất