js-OOP: Mẫu public class đầy đủ trong JavaScript – Part 5

js-OOP: Mẫu public class đầy đủ trong JavaScript – Part 5

Trong bài viết này tôi sẽ sử dụng các kỹ thuật được đưa ra từ 4 bài viết trước để xây dựng nên một mẫu cài đặt public class trong javascript với các tính năng sau:

  • 3 thành phần: variable (chứa dữ liệu), property (setter/getter), method
  • Access modifier: public/private
  • Thành phần tĩnh: static
  • Kiểm tra sự ràng buộc và yêu cầu thư viện
  • Cách ly, module hóa các lớp
(function () {
	/// kiểm tra các REFERENCES
	if (typeof (Library_Or_Class) === 'undefined') 
		throw new Error('Lỗi khi không thấy có thư viện hoặc class cần!');


	/// Định nghĩa NAMESPACE
	window.vn = window.vn || {};
	vn.eten = vn.eten || {};
	vn.eten.tek = vn.eten.tek || {};

	/// Định nghĩa Private Static Variable
	var privateStaticProperty = 0;

	/// Định nghĩa Private Static Property
	function privateStaticProperty (value) {
		if (typeof (value) === 'undefined') return privateStaticProperty;
		// validate value nếu cần
		privateStaticProperty = value;
	};

	/// Định nghĩa Private Static Method
	function privateStaticMethod() {
		// định nghĩa privateStaticMethod
	}

	/// Định nghĩa Public CLASS và khai báo constructor
	vn.eten.tek.PublicClass = function (params) {
		var _this = this;
		/// Định nghĩa Private Variable
		var privateVariable;

		/// Định nghĩa Private Property
		function privateProperty(value) {
			if (typeof (value) === 'undefined') return privateVariable;
			// validate value nếu cần
			privateVariable = value;
		};

		/// Định nghĩa Private Method
		function privateMethod() {
			// định nghĩa privateMethod
		}

		/// Định nghĩa Public Property
		this.publicProperty = function (value) {
			if (typeof (value) === 'undefined') return privateVariable;
			// validate value nếu cần
			privateVariable = value;
		};

		/// Định nghĩa Public Method
		this.publicMethod = function () {
			// định nghĩa publicMethod
		};

		/// Định nghĩa Public CONSTRUCTION
		(function () {
			// sử dụng _this như this
		})();
	};

	/// Định nghĩa Public Static Variable
	vn.eten.tek.PublicClass.publicStaticVariable = "";

	vn.eten.tek.PublicClass.publicStaticProperty = function (value) {
		if (typeof (value) === 'undefined') return privateStaticProperty;
		// validate value nếu cần
		privateStaticProperty = value;
	};

	/// Định nghĩa Public Static Method
	vn.eten.tek.PublicClass.publicStaticMethod = function () {
		// định nghĩa publicStaticMethod
	};
})();

Ví dụ cài đặt lớp theo mẫu trên

Cần cài đặt lớp Rectangular (Hình hộp chữ nhật) nằm trong namespace vn.eten.tek có các thuộc tính public chiều dài (width), chiều cao (high) và chiều sâu (deep); có các phương thức public là lấy về thể tích (getVolume), cho biết có phải là hình lập phương (isCube). Nó có một phương thức private cho biết một số có phải là số dương hay không (isPositive). Class này có thuộc tính tĩnh là màu sắc (color), một phương thức tĩnh getEdge để lấy về số cạnh của hình hộp. Nó có một biến private static lưu số cạnh của hình hộp (edge) và một phương thức private static cho biết một biến có phải là số hay không (isNumber). Class này có một hàm khởi tạo cho phép truyền chiều dài, chiều cao và chiều sâu. Class này không phụ thuộc vào một thư viện hay class nào khác.

Cài đặt của nó như sau:

(function () {
	/// kiểm tra các REFERENCES
	// 	if (typeof ($) === 'undefined') 
	//		throw new Error('vn.eten.tek.Rectangular require jQuery!');

	/// Định nghĩa NAMESPACE
	window.vn = window.vn || {};
	vn.eten = vn.eten || {};
	vn.eten.tek = vn.eten.tek || {};

	/// Định nghĩa Private Static Variable
	var edge = 12;

	/// Định nghĩa Private Static Method
	function isNumber(x) {
		return !isNaN(x);
	}

	/// Định nghĩa Public CLASS
	vn.eten.tek.Rectangular = function (width, high, deep) {
		_this = this;
		/// Định nghĩa Private Variable
		var _width, _high, _deep;

		/// Định nghĩa Private Method
		function isPositive(x) {
			return isNumber(x) && x > 0;
		}

		/// Định nghĩa Public Property
		this.width = function (value) {
			if (typeof (value) === 'undefined') return _width;
			if (!isPositive(value)) throw "Value phải là số dương";
			_width = value;
		};
		this.high = function (value) {
			if (typeof (value) === 'undefined') return _high;
			if (!isPositive(value)) throw "Value phải là số dương";
			_high = value;
		};
		this.deep = function (value) {
			if (typeof (value) === 'undefined') return _deep;
			if (!isPositive(value)) throw "Value phải là số dương";
			_deep = value;
		};

		/// Định nghĩa Public Method
		this.getVolume = function () {
			return this.width() * this.high() * this.deep();
		};

		this.isCube = function () {
			return this.width() == this.high() && this.width() == this.deep();
		};

		/// Định nghĩa Public CONSTRUCTION
		(function () {
			_this.width(width);
			_this.high(high);
			_this.deep(deep);
		})();
	};

	/// Định nghĩa Public Static Variable
	vn.eten.tek.Rectangular.color = "black";

	/// Định nghĩa Public Static Method
	vn.eten.tek.Rectangular.getEdge = function () {
		return edge;
	};
})();

Cách sử dụng:

alert("Số cạnh của hình hộp: " + vn.eten.tek.Rectangular.getEdge());
// Số cạnh của hình hộp: 12
var rec = new vn.eten.tek.Rectangular(1, 2, 2);
alert("Thể tích của hộp 1x2x2 = " + rec.getVolume());
// Thể tích của hộp 1x2x2 = 4
alert("Chiều rộng: " + rec.width());
// Chiều rộng: 1
alert("Hình hộp là lập phương: " + rec.isCube());
// Hình hộp là lập phương: false
rec.width(2);
alert("Chiều rộng sau khi tăng: " + rec.width());
// Chiều rộng sau khi tăng: 2
alert("Thể tích của hộp = " + rec.getVolume());
// Thể tích của hộp = 8
alert("Hình hộp là lập phương: " + rec.isCube());
// Hình hộp là lập phương: true

Như vậy tôi đã xây dựng được một mẫu tương đối đầy đủ giúp xây dựng được một class trong javascript. Trong bài viết sau, tôi sẽ trình bày cách cài đặt một lớp dẫn xuất (con) khi đã có lớp cha.

Khi trích dẫn bài viết từ tek.eten.vn, xin vui lòng ghi rõ nguồn. Chúng tôi sẽ rất cảm ơn bạn!