แนะนำ
โหมด Flyweight (Flyweight) ใช้เทคโนโลยีการแชร์เพื่อรองรับวัตถุที่มีความละเอียดจำนวนมากอย่างมีประสิทธิภาพหลีกเลี่ยงค่าใช้จ่ายของชั้นเรียนขนาดเล็กจำนวนมากที่มีเนื้อหาเดียวกัน (เช่นการใช้หน่วยความจำ) และอนุญาตให้ทุกคนแบ่งปันคลาส (metaclass)
รูปแบบสารานุกรมสามารถหลีกเลี่ยงค่าใช้จ่ายจำนวนมากของคลาสที่คล้ายกันมาก ในการเขียนโปรแกรมบางครั้งจำเป็นต้องสร้างอินสแตนซ์คลาสที่ละเอียดจำนวนมากเพื่อแสดงข้อมูล หากคุณพบว่าอินสแตนซ์เหล่านี้มีค่าใช้จ่ายเท่ากันยกเว้นพารามิเตอร์สองสามตัวคุณสามารถลดจำนวนคลาสที่ต้องมีการสร้างอินสแตนซ์ได้อย่างมีนัยสำคัญ หากพารามิเตอร์เหล่านั้นสามารถเคลื่อนย้ายออกไปนอกอินสแตนซ์ของชั้นเรียนและส่งผ่านเมื่อวิธีการที่เรียกว่าจำนวนของแต่ละอินสแตนซ์สามารถลดลงได้อย่างมากโดยการแบ่งปัน
แล้วถ้าคุณใช้โหมดสารานุกรมใน JavaScript ล่ะ? มีสองวิธี สิ่งแรกคือนำไปใช้กับเลเยอร์ข้อมูลส่วนใหญ่กับวัตถุที่คล้ายกันจำนวนมากในหน่วยความจำ ประการที่สองคือนำไปใช้กับเลเยอร์ DOM ซึ่งสามารถใช้กับตัวจัดการเหตุการณ์กลางเพื่อหลีกเลี่ยงการเพิ่มการจัดการเหตุการณ์ในแต่ละองค์ประกอบเด็กในคอนเทนเนอร์พาเรนต์
เพลิดเพลินกับเลเยอร์ข้อมูล
มีแนวคิดที่สำคัญสองประการในฟลายเวท - สถานะภายในและภายนอกสถานะภายนอก สถานะภายในได้รับการจัดการด้วยวิธีการภายในในวัตถุและข้อมูลภายนอกสามารถลบหรือบันทึกภายนอกได้
ในการกล่าวอย่างตรงไปตรงมามันเป็นครั้งแรกที่จะหยิกโมเดลดั้งเดิมจากนั้นสร้างโมเดลเฉพาะที่มีลักษณะที่แตกต่างกันตามโอกาสและสภาพแวดล้อมที่แตกต่างกัน เห็นได้ชัดว่าต้องมีการสร้างวัตถุใหม่ที่แตกต่างกันที่นี่ดังนั้นโหมดโรงงานมักจะปรากฏในโหมดฟลายเวท สถานะภายในของฟลายเวทใช้เพื่อแบ่งปัน Flyweight Factory รับผิดชอบในการรักษาสระว่ายน้ำฟลายเวท (พูลโหมด) เพื่อจัดเก็บวัตถุที่มีสถานะภายใน
ใช้โหมดความบันเทิง
ลองมาดูกันว่าหากระบบใช้ไลบรารีคลาสเพื่อจัดการหนังสือทั้งหมดข้อมูลเมตาของหนังสือแต่ละเล่มจะถูกตั้งค่าไว้อย่างไม่แน่นอนเป็นเนื้อหาต่อไปนี้:
การคัดลอกรหัสมีดังนี้:
รหัสประจำตัว
ชื่อ
ผู้เขียน
ประเภท
จำนวนหน้า
ID สำนักพิมพ์
isbn
นอกจากนี้เรายังต้องกำหนดเวลาและผู้กู้ของหนังสือแต่ละเล่มรวมถึงวันที่ส่งคืนและไม่ว่าจะมี:
การคัดลอกรหัสมีดังนี้:
checkoutdate
checkoutmember
duereturndate
ความพร้อม
เนื่องจากวัตถุหนังสือถูกตั้งค่าเป็นรหัสต่อไปนี้โปรดทราบว่ารหัสยังไม่ได้รับการปรับให้เหมาะสม:
การคัดลอกรหัสมีดังนี้:
var book = function (id, ชื่อ, ผู้แต่ง, ประเภท, pagecount, publisherid, isbn, checkoutdate, checkoutmember, duereturndate, ความพร้อมใช้งาน) {
this.id = id;
this.title = title;
this.author = ผู้แต่ง;
this.genre = ประเภท;
this.pagecount = pagecount;
this.publisherId = PublisherId;
this.isbn = isbn;
this.checkoutdate = checkoutdate;
this.checkoutmember = checkoutmember;
this.duereturndate = duereturndate;
สิ่งนี้ความพร้อมใช้งาน = ความพร้อมใช้งาน;
-
book.prototype = {
getTitle: function () {
ส่งคืนสิ่งนี้ title;
-
getAuthor: function () {
ส่งคืนสิ่งนี้
-
getisbn: function () {
คืนสิ่งนี้ ISBN;
-
/*วิธีการรับอื่น ๆ จะไม่ปรากฏที่นี่*//
// อัปเดตสถานะการให้กู้ยืม
updateCheckOutStatus: function (bookid, newstatus, checkoutdate, checkoutmember, newreturndate) {
this.id = bookid;
this.availability = newstatus;
this.checkoutdate = checkoutdate;
this.checkoutmember = checkoutmember;
this.duereturndate = newreturndate;
-
//ต่ออายุ
ExtionCheckOutPeriod: ฟังก์ชั่น (bookid, newreturndate) {
this.id = bookid;
this.duereturndate = newreturndate;
-
// มันหมดอายุหรือไม่
ispastdue: ฟังก์ชั่น (bookid) {
var currentDate = วันที่ใหม่ ();
ส่งคืน currentDate.getTime ()> date.parse (this.duereturndate);
-
-
โปรแกรมอาจจะดีในตอนแรก แต่เมื่อเวลาผ่านไปหนังสืออาจเพิ่มขึ้นในปริมาณมากและหนังสือแต่ละประเภทมีรุ่นและปริมาณที่แตกต่างกันคุณจะพบว่าระบบเริ่มช้าลงและช้าลง วัตถุหนังสือหลายพันรายการสามารถจินตนาการได้ในหน่วยความจำและเราจำเป็นต้องใช้โหมดสารานุกรมเพื่อปรับให้เหมาะสม
เราสามารถแบ่งข้อมูลออกเป็นข้อมูลภายในและภายนอกสองประเภท ข้อมูลที่เกี่ยวข้องกับวัตถุหนังสือ (ชื่อเรื่องผู้แต่ง ฯลฯ ) สามารถนำมาประกอบกับคุณสมบัติภายในในขณะที่ (checkoutmember, duereturndate ฯลฯ ) สามารถนำมาประกอบกับคุณสมบัติภายนอก ด้วยวิธีนี้รหัสต่อไปนี้สามารถแบ่งปันวัตถุเดียวกันในหนังสือเล่มเดียวกันได้เพราะไม่ว่าใครจะยืมหนังสือตราบใดที่หนังสือเล่มนี้เป็นหนังสือเล่มเดียวกันข้อมูลพื้นฐานก็เหมือนกัน:
การคัดลอกรหัสมีดังนี้:
/*รหัสการเพิ่มประสิทธิภาพโหมด Xienyuan*//
var book = function (ชื่อ, ผู้แต่ง, ประเภท, pagecount, publisherid, isbn) {
this.title = title;
this.author = ผู้แต่ง;
this.genre = ประเภท;
this.pagecount = pagecount;
this.publisherId = PublisherId;
this.isbn = isbn;
-
กำหนดโรงงานพื้นฐาน
มากำหนดโรงงานพื้นฐานเพื่อตรวจสอบว่าวัตถุของหนังสือถูกสร้างขึ้นมาก่อนกลับมาหรือไม่หากมีและสร้างใหม่และจัดเก็บมันเพื่อให้สามารถเข้าถึงได้ในภายหลัง
การคัดลอกรหัสมีดังนี้:
/* Book Factory Singleton*/
var bookfactory = (ฟังก์ชัน () {
var ที่มีอยู่หนังสือ = {};
กลับ{
CreateBook: function (ชื่อ, ผู้แต่ง, ประเภท, pagecount, publisherid, isbn) {
/*ค้นหาว่าจะสร้างก่อนหน้า*/
var justingbook = books ที่มีอยู่ [isbn];
if (amedingbook) {
ส่งคืนสมุดที่มีอยู่
}อื่น{
/ * ถ้าไม่สร้างและบันทึก */
var book = หนังสือเล่มใหม่ (ชื่อ, ผู้แต่ง, ประเภท, pagecount, publisherid, isbn);
หนังสือที่มีอยู่ [isbn] = หนังสือ;
หนังสือคืน;
-
-
-
-
จัดการสถานะภายนอก
สถานะภายนอกค่อนข้างง่าย ยกเว้นหนังสือที่เราห่อหุ้มทุกอย่างอื่น ๆ จะต้องมีการจัดการที่นี่:
การคัดลอกรหัสมีดังนี้:
/*BookRecordManager Singleton สำหรับการจัดการยืม*//
var bookRecordManager = (function () {
var bookRecordDatabase = {};
กลับ{
/*เพิ่มบันทึกการยืมหนังสือ*/
addBookRecord: ฟังก์ชั่น (ID, ชื่อ, ผู้แต่ง, ประเภท, pagecount, publisherId, isbn, checkoutdate, checkoutmember, duereturndate, ความพร้อมใช้งาน) {
var book = bookfactory.createbook (ชื่อ, ผู้แต่ง, ประเภท, pagecount, publisherid, isbn);
BookRecordDatabase [id] = {
checkoutmember: checkoutmember,
CheckOutDate: CheckOutDate
duereturndate: duereturndate
ความพร้อมใช้งาน: ความพร้อมใช้งาน
หนังสือ: หนังสือ;
-
-
updateCheckOutStatus: function (bookid, newstatus, checkoutdate, checkoutmember, newreturndate) {
var record = bookRecordDatabase [bookid];
record.availability = newstatus;
record.CheckOutDate = CheckOutDate;
record.CheckOutMember = CheckOutMember;
record.duereturndate = newreturndate;
-
ExtionCheckOutPeriod: ฟังก์ชั่น (bookid, newreturndate) {
BookRecordDatabase [bookid] .duereturndate = newreturndate;
-
ispastdue: ฟังก์ชั่น (bookid) {
var currentDate = วันที่ใหม่ ();
ส่งคืน currentDate.getTime ()> date.parse (bookRecordDatabase [bookid] .duereturndate);
-
-
-
ด้วยวิธีนี้เราได้บันทึกข้อมูลเดียวกันของหนังสือเล่มเดียวกันในวัตถุ BookManager และบันทึกเพียงหนึ่งสำเนา; เมื่อเทียบกับรหัสก่อนหน้านี้เราสามารถพบว่ามันบันทึกหน่วยความจำจำนวนมาก
เพลิดเพลินไปกับโหมดหยวนและ DOM
ฉันจะไม่พูดอะไรมากเกี่ยวกับเหตุการณ์ DOM ที่นี่ ฉันเชื่อว่าทุกคนรู้อยู่แล้ว มาให้สองตัวอย่าง
ตัวอย่างที่ 1: การจัดการเหตุการณ์ส่วนกลาง
ตัวอย่างเช่นหากเราต้องการตรวจสอบเหตุการณ์การคลิกสำหรับองค์ประกอบหรือโครงสร้างที่คล้ายกันมากมาย (เช่นเมนูหรือหลาย LIs ใน UL) เราต้องผูกเหตุการณ์สำหรับแต่ละองค์ประกอบ หากมีองค์ประกอบมากมายมากการแสดงสามารถจินตนาการได้ เมื่อรวมกับความรู้เกี่ยวกับฟองสบู่หากมีการเรียกองค์ประกอบของเด็กใด ๆ เหตุการณ์จะฟองไปยังองค์ประกอบระดับก่อนหน้าหลังจากทริกเกอร์ถูกทริกเกอร์ ดังนั้นการใช้คุณสมบัตินี้เราสามารถใช้โหมดสารานุกรมเราสามารถตรวจสอบเหตุการณ์เหตุการณ์ในองค์ประกอบหลักขององค์ประกอบที่คล้ายกันเหล่านี้จากนั้นตัดสินว่าองค์ประกอบของเด็กที่มีเหตุการณ์ที่เกิดขึ้นแล้วดำเนินการเพิ่มเติม
ที่นี่เรารวมวิธีการผูก/unbind ของ jQuery เพื่อยกตัวอย่าง
html:
การคัดลอกรหัสมีดังนี้:
<div id = "container">
<div href = "#"> ข้อมูลเพิ่มเติม (ที่อยู่)
<span>
นี่คือข้อมูลเพิ่มเติม
</span> </div>
<div href = "#"> ข้อมูลเพิ่มเติม (แผนที่)
<span>
<iframe src = "http://www.map-generator.net/extmap.php?name=london&address=london%2C%20England&width=500...gt;" </iframe>
</span>
</div>
</div>
JavaScript:
การคัดลอกรหัสมีดังนี้:
statemanager = {
บิน: ฟังก์ชั่น () {
var self = this;
$ ('#container'). unbind (). bind ("คลิก" ฟังก์ชัน (e) {
var target = $ (e.originaltarget || e.srcelement);
// กำหนดองค์ประกอบของเด็กที่เป็น
if (target.is ("div.toggle")) {
self.handleclick (เป้าหมาย);
-
-
-
handleclick: ฟังก์ชั่น (elem) {
elem.find ('span'). สลับ ('ช้า');
-
-
ตัวอย่างที่ 2: การใช้โหมดสารานุกรมเพื่อปรับปรุงประสิทธิภาพ
อีกตัวอย่างหนึ่งยังคงเกี่ยวข้องกับ jQuery โดยทั่วไปเราใช้วัตถุองค์ประกอบในฟังก์ชันการโทรกลับเหตุการณ์ เรามักจะใช้รูปแบบของ $ (นี้) ในความเป็นจริงมันสร้างวัตถุใหม่ซ้ำ ๆ เพราะสิ่งนี้ในฟังก์ชั่นการโทรกลับเป็นองค์ประกอบ DOM แล้ว เราต้องใช้รหัสต่อไปนี้:
การคัดลอกรหัสมีดังนี้:
$ ('div'). bind ('คลิก', function () {
console.log ('คุณคลิก:' + $ (นี่) .attr ('id'));
-
// ควรหลีกเลี่ยงรหัสข้างต้นและหลีกเลี่ยงการสร้างวัตถุ jQuery บนองค์ประกอบ DOM อีกครั้งเพราะคุณสามารถใช้องค์ประกอบ DOM ได้โดยตรง
$ ('div'). bind ('คลิก', function () {
console.log ('คุณคลิก:' + this.id);
-
ในความเป็นจริงถ้าเราต้องใช้รูปแบบของ $ (นี้) เรายังสามารถใช้รูปแบบอินสแตนซ์รุ่นเดียวของเราเองได้เช่นเราสามารถใช้ฟังก์ชันเช่น jQuery.signle (นี้) เพื่อส่งคืนองค์ประกอบ DOM เอง:
การคัดลอกรหัสมีดังนี้:
jQuery.single = (ฟังก์ชั่น (o) {
var collection = jQuery ([1]);
ฟังก์ชั่น return (องค์ประกอบ) {
// ใส่องค์ประกอบในคอลเลกชัน
คอลเลกชัน [0] = องค์ประกอบ;
// กลับไปที่คอลเลกชัน
คอลเลกชันกลับ;
-
-
วิธีใช้:
การคัดลอกรหัสมีดังนี้:
$ ('div'). bind ('คลิก', function () {
var html = jQuery.single (นี่) .next (). html ();
console.log (html);
-
ด้วยวิธีนี้องค์ประกอบ DOM เองจะถูกส่งกลับตามที่เป็นอยู่และไม่ได้สร้างวัตถุ jQuery
สรุป
โหมด Flyweight เป็นโหมดที่ปรับปรุงประสิทธิภาพของโปรแกรมและประสิทธิภาพซึ่งจะเพิ่มความเร็วในการทำงานของโปรแกรมอย่างมาก มีสถานการณ์แอปพลิเคชันมากมาย: ตัวอย่างเช่นหากคุณต้องการอ่านชุดสตริงจากฐานข้อมูลหลายสายเหล่านี้ซ้ำแล้วซ้ำอีกเราสามารถเก็บสตริงเหล่านี้ไว้ในสระน้ำ (พูล)
หากแอปพลิเคชันใช้วัตถุจำนวนมากและวัตถุจำนวนมากเหล่านี้ทำให้เกิดการจัดเก็บที่ดีคุณควรพิจารณาใช้โหมดสารานุกรม และสถานะของวัตถุส่วนใหญ่อาจเป็นภายนอก หากสถานะภายนอกของวัตถุถูกลบวัตถุจำนวนมากสามารถแทนที่ด้วยวัตถุที่ใช้ร่วมกันได้น้อย ในเวลานี้คุณสามารถพิจารณาใช้โหมดสารานุกรม