2015-07-12 17 views
5

Tôi hiện đang làm việc trên một dự án mà cấu trúc thừa kế sau đây được sử dụng:Thừa kế cổ điển và Object Pooling

var Type = function(a){ 
    this.a = a; 
}; 

var SubType = function(a){ 
    Type.call(this, a); 
}; 
SubType.prototype = Object.create(Type.prototype); 
SubType.prototype.constructor = SubType; 

Bây giờ, tôi đang cố gắng thêm một số đối tượng tổng hợp để phương trình. Các mô hình Tôi hiện đang sử dụng tác phẩm một cái gì đó tương tự (giả):

Type.new = function(){ 
    if object available in pool 
    reset popped pool object 
    return pool object 
    else 
    return new Type() 
} 
var a = Type.new(); 

Tất nhiên, vấn đề với việc sử dụng hai mô hình này là các cuộc gọi constructor trên kiểu phụ sẽ không rút ra từ hồ bơi Loại của. Có cách nào xung quanh điều này mà không cần chuyển sang cấu trúc nhà máy? I E. là có một cách, trong một constructor, để làm một cái gì đó dọc theo dòng:

var SubType = function(){ 
    build on top of instanceReturnedFromFunction() 
}; 

Biết nó không phải luôn luôn nhất quán trên các bối cảnh, tôi muốn cũng muốn duy trì cấu trúc thừa kế để instanceof vv sẽ vẫn làm việc :

+0

"Cấu trúc nhà máy" là gì và tại sao bạn muốn tránh điều đó? – Bergi

+0

Theo cấu trúc nhà máy, tôi có nghĩa là tái cấu trúc từ các nhà xây dựng/mới đến một cái gì đó dọc theo các dòng của 'function Type (a) {return {a: a}}'. Về lý do tại sao: nó sẽ liên quan đến một số lượng tái cấu trúc, và sẽ loại trừ việc sử dụng một số nhà khai thác sẵn có (ví dụ, vv) – Nodehead

+0

Ah, tôi hiểu. Tôi nghĩ bạn có nghĩa là nhà máy 'Type.new'… – Bergi

Trả lời

4

vấn đề với việc sử dụng mô hình này là nhà xây dựng mà các cuộc gọi trên SubType sẽ không rút ra từ hồ bơi Type 's

Trong thực tế đó không phải là một vấn đề, đó là một điều cần thiết. TypeSubType trường hợp có các nguyên mẫu khác nhau, bạn không thể sử dụng chúng thay thế lẫn nhau (và swapping prototypes doesn't work either).
Bạn chắc chắn sẽ cần các hồ bơi riêng cho tất cả các lớp học của mình. Và bạn có thể sử dụng cách tiếp cận .new nhà máy mà không cần bất kỳ vấn đề - mặc dù tất nhiên bạn nên tạo những nhà máy programatically:

function pooledNew() { 
    // `this` is the "class" constructor function 
    if (!this.pool) this.pool = []; 
    var instance = this.pool.length ? this.pool.pop() : Object.create(this.prototype); 
    this.apply(instance, arguments); // reset/initialise 
    return instance; 
} 
function makePooling(constr) { 
    constr.new = pooledNew; 
    constr.pool = []; 
    var proto = constr.prototype; 
    if (proto.constructor !== constr) 
     proto.constructor = constr; 
    if (typeof proto.destroy != "function") 
     proto.destroy = function destroyInstance() { 
      this.constructor.pool.push(this); 
     }; 
    return constr; 
} 

Đây là những thiết kế để làm việc một cách hoàn hảo với subclassing, trong ví dụ của bạn chỉ cần làm

makePooling(Type); 
makePooling(SubType); 

Trong ES6, các lớp con thậm chí sẽ kế thừa phương thức new từ các hàm tạo lớp cha của chúng.

class Type { 
    constructor(a) { 
     this.a = a; 
    } 
    destroy() { // overwriting default behaviour 
     this.a = null; // for GC 
     this.constructor.pool.push(this); 
    } 
} 
makePooling(Type); 

class SubType extends Type { 
    // you can use super calls in both "constructor" and "destroy" methods 
} 
+1

Brilliant. Cảm ơn bạn về thông tin. Tôi chưa có đại diện để bỏ phiếu cho câu trả lời, nhưng tôi đã đánh dấu nó là đã được chấp nhận: trả lời câu hỏi của tôi! Cảm ơn một lần nữa. – Nodehead

+1

@MrMe: Bây giờ bạn có đặc quyền :-) Người hỏi câu hỏi được viết tốt, chào mừng bạn đến với Stack Overflow! – Bergi