JavaRush /Blog Java /Random-VI /Mẫu và Singleton - dành cho tất cả những người lần đầu ti...

Mẫu và Singleton - dành cho tất cả những người lần đầu tiên gặp chúng

Xuất bản trong nhóm
Bài viết này hướng đến những người lần đầu tiên biết đến khái niệm hoa văn, đã nghe nói về Singletone hoặc bằng cách nào đó đã làm ra nó nhưng vẫn chưa hiểu gì cả. Chào mừng! Học sinh JavaRush lần đầu tiên gặp các mẫu ở cấp 15, khi bất ngờ, giới hạn yêu cầu “sửa” và triển khai một mẫu Singletonvới cách triển khai lười biếng. Những học sinh lần đầu tiên nghe về nó Singletonsẽ ngay lập tức đặt ra một loạt câu hỏi: mẫu là gì, tại sao nó lại cần thiết, loại mẫu đó là gì Singletonvà cuối cùng, đây là kiểu triển khai lười biếng như thế nào. Hãy bắt đầu trả lời theo thứ tự: Patterns và Singleton - dành cho những ai lần đầu gặp chúng - 1

Dù sao thì mô hình là gì?

Để hiểu rõ hơn, tôi nghĩ đáng để trả lời câu hỏi này từ lịch sử. Trong số các lập trình viên có bốn tác giả nổi tiếng: Erich Gamma, Richard Helm, Ralph Johnson và John Vlissides, người đã nghĩ ra một ý tưởng thú vị.
Patterns và Singleton - dành cho những người lần đầu tiên gặp chúng - 2
Họ nhận thấy rằng khi viết chương trình, họ thường phải giải những bài toán gần giống nhau và viết mã cùng loại về cấu trúc. Vì vậy, họ quyết định mô tả dưới dạng các mẫu hình điển hình thường được sử dụng trong lập trình hướng đối tượng. Cuốn sách được xuất bản năm 1995 với tựa đề “Kỹ thuật thiết kế hướng đối tượng”. Mẫu thiết kế" . Tiêu đề của cuốn sách hóa ra quá dài và nó được biết đến đơn giản với cái tên Cuốn sách của bốn tên tội phạm . Trong ấn bản đầu tiên, 23 mẫu đã được xuất bản, sau đó hàng chục mẫu khác đã được phát hiện. Vì vậy, để trả lời câu hỏi trong đoạn này, “Mẫu là gì?” , hãy tóm tắt chỉ trong vài từ:
Mẫu là một giải pháp được tiêu chuẩn hóa cho một vấn đề chung.
Singletonđây chỉ là một trong những mẫu này.

Tại sao chúng ta cần mẫu (mẫu thiết kế)

Bạn có thể lập trình mà không cần biết các mẫu; bạn có thể xác minh điều này một cách đơn giản bằng cách nhận ra thực tế là ở cấp độ 15 trong JavaRush, bạn đã viết hàng trăm chương trình nhỏ mà không biết gì về sự tồn tại của chúng. Điều này cho thấy rằng mẫu là một loại công cụ, sự hiện diện của nó giúp phân biệt một bậc thầy với một người nghiệp dư:
Patterns và Singleton - dành cho những ai lần đầu gặp chúng - 3
Các mẫu mô tả cách giải quyết chính xác một trong những vấn đề điển hình. Kết quả là, biết các mẫu giúp bạn tiết kiệm thời gian. Một sự tương tự có thể được thực hiện với các thuật toán. Ví dụ: bạn có thể nghĩ ra thuật toán sắp xếp của riêng mình với blackjack và các con số và dành nhiều thời gian cho nó hoặc bạn có thể sử dụng một thuật toán đã được mô tả từ lâu và triển khai nó. Điều này cũng tương tự với các mẫu. Ngoài ra, với việc sử dụng các mẫu, mã sẽ trở nên chuẩn hóa hơn và khi sử dụng đúng mẫu, bạn sẽ ít mắc lỗi hơn vì chúng đã được đoán trước và loại bỏ trong mẫu này. Ngoài ra, kiến ​​thức về các mẫu cho phép các lập trình viên hiểu nhau hơn. Chỉ cần nói tên của mẫu là đủ, thay vì cố gắng giải thích cho các lập trình viên đồng nghiệp của bạn những gì bạn muốn họ làm. Vì vậy, tóm lại, các mẫu thiết kế giúp:
  • không phát minh lại bánh xe mà sử dụng các giải pháp tiêu chuẩn;
  • chuẩn hóa mã;
  • chuẩn hóa thuật ngữ;
Để kết luận phần này, chúng tôi lưu ý rằng toàn bộ các mẫu có thể được đơn giản hóa thành ba nhóm lớn:
Patterns và Singleton - dành cho những người lần đầu tiên gặp chúng - 4

Cuối cùng là mẫu Singleton

Singletonđề cập đến các mô hình sáng tạo . Bản dịch theo nghĩa đen của nó là cô đơn. Mẫu này đảm bảo rằng một lớp chỉ có một đối tượng (một phiên bản của lớp) và một điểm truy cập toàn cầu được cung cấp cho đối tượng đó. Cần phải rõ ràng từ mô tả rằng mẫu này nên được sử dụng trong hai trường hợp:
  1. khi không nên tạo nhiều hơn một đối tượng của bất kỳ lớp nào trong chương trình của bạn. Ví dụ: trong trò chơi máy tính, bạn có lớp “Nhân vật” và lớp này chỉ được có một đối tượng mô tả chính nhân vật đó.

  2. khi bạn cần cung cấp điểm truy cập toàn cầu cho một đối tượng lớp. Nói cách khác, bạn cần đảm bảo rằng đối tượng được gọi từ bất kỳ đâu trong chương trình. Và, than ôi, đối với điều này, chỉ tạo một biến toàn cục là chưa đủ, bởi vì nó không được bảo vệ chống ghi và bất kỳ ai cũng có thể thay đổi giá trị của biến này và điểm truy cập toàn cục vào đối tượng sẽ bị mất. Các thuộc tính này Singletoncần thiết, chẳng hạn như khi bạn có một đối tượng của một lớp làm việc với cơ sở dữ liệu và bạn cần có thể truy cập được cơ sở dữ liệu đó từ các phần khác nhau của chương trình. Và Singletonnó sẽ đảm bảo rằng không có mã nào khác thay thế thể hiện của lớp được tạo trước đó.
Hai vấn đề này được giải quyết bằng cách Singleton: chỉ có một đối tượng trong chương trình và phải có quyền truy cập toàn cục vào nó. Trong ví dụ ở cấp 15, giới hạn yêu cầu triển khai mẫu này cho nhiệm vụ sau (đây là mô tả của nó):
Mẫu và Singleton - dành cho tất cả những người lần đầu tiên gặp chúng - 5
Sau khi đọc kỹ điều kiện, bạn sẽ hiểu rõ tại sao chính xác Singleton(Đơn) lại cần thiết ở đây. Cuối cùng, chương trình yêu cầu bạn tạo một đối tượng cho mỗi lớp: Sun, Moon, Earth. Và thật hợp lý khi giả định rằng mỗi lớp trong chương trình không nên tạo nhiều hơn một Mặt trời/Mặt trăng/Trái đất, nếu không sẽ là vô lý, trừ khi tất nhiên bạn đang viết phiên bản Chiến tranh giữa các vì sao của riêng mình. Tính năng triển khai SingletonJava theo ba bước Không thể triển khai hành vi Singleton trong Java bằng cách sử dụng một hàm tạo thông thường vì hàm tạo đó luôn trả về một đối tượng mới. Do đó, tất cả việc triển khai Singleton'a đều đi đến việc ẩn hàm tạo và tạo một phương thức tĩnh công khai sẽ kiểm soát sự tồn tại của một đối tượng duy nhất và "hủy" tất cả các đối tượng mới xuất hiện. Nếu Singleton'a được gọi, nó phải tạo một đối tượng mới (nếu nó chưa có trong chương trình) hoặc trả về một đối tượng đã được tạo. Để làm điều này: #1. – Bạn cần thêm một trường tĩnh riêng vào lớp chứa một đối tượng:
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance; //#1
}
#2. – Đặt hàm tạo của lớp (hàm tạo mặc định) ở chế độ riêng tư (để quyền truy cập vào nó bị đóng bên ngoài lớp, khi đó nó sẽ không thể trả về các đối tượng mới):
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){} // #2
}
#3 . – Khai báo một phương thức tạo tĩnh sẽ được sử dụng để lấy singleton:
public class LazyInitializedSingleton {
    private static LazyInitializedSingleton instance;
        private LazyInitializedSingleton(){}
        public static LazyInitializedSingleton getInstance(){ // #3
        if(instance == null){		//if the object has not been created yet
            instance = new LazyInitializedSingleton();	//create a new object
        }
        return instance;		// return the previously created object
    }
}
Ví dụ trên hơi vụng về, vì chúng ta chỉ đơn giản ẩn hàm tạo và cung cấp phương thức của riêng mình thay vì hàm tạo tiêu chuẩn. Vì bài viết này nhằm mục đích giúp sinh viên JavaRush tiếp xúc với mẫu này (và các mẫu nói chung) lần đầu tiên nên các tính năng triển khai của Singletons phức tạp hơn sẽ không được đưa ra ở đây. Chúng tôi chỉ lưu ý rằng tùy thuộc vào độ phức tạp của chương trình, có thể cần phải sàng lọc chi tiết hơn mẫu này. Ví dụ: trong môi trường đa luồng (xem chủ đề Luồng), một số luồng khác nhau có thể đồng thời gọi phương thức getter của Singleton và mã được mô tả ở trên sẽ ngừng hoạt động, vì mỗi luồng riêng lẻ sẽ có thể tạo nhiều phiên bản của lớp một lần. Do đó, vẫn có một số cách tiếp cận khác nhau để tạo ra các singleton an toàn cho Thread. Nhưng đó lại là một câu chuyện khác =)) Và cuối cùng. Khởi tạo lười biếng mà giới hạn yêu cầu là gì ?Khởi tạo lười biếng còn được gọi là khởi tạo lười biếng. Đây là một kỹ thuật lập trình trong đó một hoạt động sử dụng nhiều tài nguyên (và việc tạo một đối tượng là một hoạt động sử dụng nhiều tài nguyên) được thực hiện theo yêu cầu, thay vì thực hiện trước. Về cơ bản đó là những gì xảy ra trong mã của chúng tôi Singleton'a. Nói cách khác, đối tượng của chúng tôi được tạo tại thời điểm nó được truy cập chứ không phải trước đó. Không nên cho rằng khái niệm khởi tạo lười biếng bằng cách nào đó có mối liên hệ chặt chẽ với Singleton'om. Khởi tạo lười biếng cũng được sử dụng trong các mẫu thiết kế tổng quát khác, ví dụ như trong Proxy và Factory Method, nhưng đó lại là một câu chuyện khác =) Các nguồn sau đây đã được sử dụng để chuẩn bị cho bài viết:
  1. Mẫu thiết kế Java Singleton Thực tiễn tốt nhất kèm theo ví dụ
  2. Mẫu thiết kế
  3. Singleton đúng trong Java
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION