11

Gần đây tôi đã quen thuộc với mô hình tiết lộ mô-đun và tôi đã đọc khá một vài bài viết về nó.Tiết lộ mô hình mô hình khó khăn

Nó có vẻ giống như một mô hình rất tốt và tôi muốn bắt đầu sử dụng nó trong một dự án lớn mà tôi có. Trong dự án tôi đang sử dụng: Jquery, KO, requirejs, Jquery Mobile, JayData. Có vẻ như với tôi, nó sẽ phù hợp với KO ViewModels.

Cụ thể, tôi muốn sử dụng phiên bản THIS của nó.

Một điều tôi không thể tìm thấy là bất lợi khi sử dụng mẫu này, có phải vì không có bất kỳ (tôi thấy khó tin)?

Tôi nên cân nhắc điều gì trước khi bắt đầu sử dụng?

+2

Kiểm tra bài viết này: http://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript có phần bất lợi ở cuối. – nemesv

+0

Mẫu mô-đun dứt khoát cũng vượt qua một số nhược điểm với mô hình mô-đun và mô hình tiết lộ (như khớp nối chặt chẽ với câu lệnh trả về, cách khai báo các hàm công khai và riêng tư, không gian tên không khai báo cho các chương trình con riêng và công khai. chữ với câu lệnh return): http://github.com/tfmontague/definitive-module-pattern – tfmontague

Trả lời

4

Tôi đọc bài viết mà @nemesv đã giới thiệu đến tôi (Cảm ơn :)) và tôi nghĩ có thêm một bất lợi nữa không được đề cập, vì vậy tôi nghĩ tôi sẽ thêm nó vào đây để tham khảo. Dưới đây là một trích dẫn từ bài viết:

Nhược

Một nhược điểm của mô hình này là nếu một chức năng riêng đề cập đến một chức năng công cộng, mà public function không thể được ghi đè nếu một bản vá là cần thiết. Điều này là do chức năng riêng tư sẽ tiếp tục đến đề cập đến việc triển khai riêng tư và mẫu không áp dụng cho thành viên công khai, chỉ cho các chức năng.

Thành viên đối tượng công cộng tham chiếu tới biến riêng tư cũng là tùy thuộc vào quy tắc không có quy tắc vá lỗi ở trên. Do đó, các mô-đun được tạo ra với mô hình Mô-đun Tiết lộ có thể dễ vỡ hơn so với các mô-đun được tạo bằng mẫu Mô-đun ban đầu, vì vậy cần chú ý trong quá trình sử dụng.

Và bổ sung của tôi:

Bạn không thể sử dụng thừa kế với mô hình này. Ví dụ:

var Obj = function(){ 
    //do some constructor stuff 
} 

var InheritingObj = function(){ 
    //do some constructor stuff 
} 

InheritingObj.prototype = new Obj(); 

InheritingObj.prototype.constructor = InheritingObj; 

Đây là một ví dụ đơn giản cho các thừa kế trong js, nhưng khi sử dụng Revealing Prototype Pattern bạn sẽ cần phải làm điều này:

InheritingObj.prototype = (function(){ 
    //some prototype stuff here 
}()); 

đó sẽ ghi đè lên bạn thừa kế.

+0

Dường như nó hoạt động hoàn hảo với Object.create (urlBuilder); Một cách khác để làm việc thừa kế là theo cách này http://jsfiddle.net/d0n7kfmx/ bạn nghĩ sao? – user2734550

13

Mô hình mô-đun tiết lộ (RMP) tạo ra các đối tượng không hoạt động tốt đối với việc ghi đè. Kết quả là, các đối tượng được tạo ra bằng cách sử dụng RMP không hoạt động tốt như các nguyên mẫu. Vì vậy, nếu bạn đang sử dụng RMP để tạo ra các đối tượng sẽ được sử dụng trong một chuỗi thừa kế, chỉ cần không. Quan điểm này là của riêng tôi, trái ngược với những người đề xuất của Mô hình nguyên mẫu tiết lộ.

Để xem các hành vi thừa kế xấu, lấy ví dụ sau đây của một người thợ xây url:

function rmpUrlBuilder(){ 
    var _urlBase = "http://my.default.domain/"; 
    var _build = function(relUrl){ 
    return _urlBase + relUrl; 
    }; 

    return { 
    urlBase: _urlBase, 
    build: _build 
    } 
} 

Thiết sang một bên câu hỏi tại sao bạn sẽ sử dụng RMP cho một đối tượng không có thành phần tư nhân, lưu ý rằng nếu bạn lấy đối tượng trả về và ghi đè urlBase bằng "http://stackoverflow.com", bạn sẽ mong đợi hành vi của build() để thay đổi một cách thích hợp. Không, như đã thấy trong những điều sau đây:

var builder = new rmpUrlBuilder(); 
builder.urlBase = "http://stackoverflow.com"; 
console.log(builder.build("/questions"); // prints "http://my.default.domain/questions" not "http://stackoverflow.com/questions" 

Contrast hành vi với url sau xây dựng thực hiện

function urlBuilder = function(){ 
    return { 
    urlBase: "http://my.default.domain/". 
    build: function(relUrl){ return this.urlBase + relUrl;} 
    } 
} 

var builder = new urlBuilder(); 
builder.urlBase = "http://stackoverflow.com"; 
console.log(builder.build()); // prints "http://stackoverflow.com/questions" 

mà cư xử một cách chính xác.

Bạn có thể sửa hành vi kiểu mô-đun của Tiết lộ bằng cách sử dụng phạm vi này như sau đây

function rmpUrlBuilder(){ 
    var _urlBase = "http://my.default.domain/"; 
    var _build = function(relUrl){ 
    return this.urlBase + relUrl; 
    }; 

    return { 
    urlBase: _urlBase, 
    build: _build 
    } 
} 

nhưng điều đó chứ không phải đánh bại mục đích của Pattern Mô-đun Tiết lộ. Để biết thêm chi tiết, xem blog của tôi gửi http://ilinkuo.wordpress.com/2013/12/28/defining-return-object-literals-in-javascript/

-2

nhược điểm khác với các mẫu mô-đun Tiết lộ bao gồm:

  1. khớp nối chặt chẽ của các chức năng công cộng với tuyên bố Return
  2. sử dụng hỗn hợp của đối tượng theo nghĩa đen cho các chức năng công cộng và khai báo độc lập cho các chức năng riêng tư

Tôi muốn khuyên bạn sử dụng Mẫu mô-đun dứt khoát qua Khuôn mẫu mô-đun tiết lộ (https://github.com/tfmontague/definitive-module-pattern)

+0

Tôi sẽ không đề xuất mẫu này vì nó không khác biệt nhiều so với mẫu mô-đun tiết lộ. Nó chia sẻ những thiếu sót tương tự đối với ghi đè và nguyên mẫu như trong câu trả lời được chấp nhận. –

+0

Câu hỏi đặt ra là về những bất lợi của mô hình Mô-đun lộ diện. Đó không phải là quyết định sử dụng Mô-đun Mô-đun. – tfmontague

Các vấn đề liên quan