2009-03-06 22 views
16

Tôi hiện đang đối mặt với một câu hỏi hóc búa: Cách phù hợp để kết nối với nhau 2 đối tượng javascript là gì?Cách phù hợp để nối hai đối tượng javascript với nhau là gì?

Hãy tưởng tượng một ứng dụng như trình chỉnh sửa văn bản với nhiều tệp khác nhau. Tôi có một số trang HTML đại diện cho quan điểm cho sổ ghi chép. Tôi có tệp notebook.js chứa các định nghĩa lớp cho NotebookController và Notebook View.

NotebookĐối tượng đối tượng chịu trách nhiệm thực hiện logic nghiệp vụ trên Notebook như "Lưu sổ ghi chép", "Tải sổ ghi chép", "Sổ tay mới". NotebookView chịu trách nhiệm quản lý HTML được sử dụng để trình bày. Nó hoạt động ở mức độ thấp như "get/set notebook body" "lấy/đặt tên sổ ghi chép." Nó cũng lắng nghe các sự kiện DOM (onClick) và kích hoạt các sự kiện kinh doanh (saveNotebook). Đây là nỗ lực của tôi ở mẫu Chế độ xem thụ động.

Tôi muốn mã phía máy khách javascript của tôi hướng đối tượng, phân tách mối quan tâm và đơn vị có thể kiểm chứng. Tôi muốn thử nghiệm NotebookController với NotebookView giả lập và ngược lại. Điều này có nghĩa là tôi không thể khởi tạo NotebookView bên trong NotebookController. Vì vậy, làm tôi

  • Đặt một số logic trong notebook.js tôi rằng dây 2 cùng
  • Có một chức năng toàn cầu trong ứng dụng của tôi mà biết để nhanh chóng một trong mỗi và dây chúng lại với nhau
  • Sử dụng Dependency Injection, hoặc là một trang trại được trồng tại nhà hoặc giống như SquirrelIoc

Trong Java, lựa chọn là tự nhiên: sử dụng Spring. Nhưng điều đó dường như không phải là JavaScript-y. Điều phải làm là gì?

+0

Có lẽ tôi đang thiếu một cái gì đó, nhưng bạn không thể đạt được bằng cách chỉ testability đảm bảo rằng bạn đang sử dụng tập hợp thay vì thành phần? –

+0

Đó là ý tưởng. Nhưng câu hỏi thực sự là cách phù hợp để kết hợp các vật thể đó là gì? –

Trả lời

0

Tôi sẽ cố gắng thực hiện điều này, nhưng sẽ hơi khó khăn nếu không thấy bất kỳ mã thực tế nào. Cá nhân, tôi chưa bao giờ thấy bất cứ ai làm một nỗ lực cụ thể tại (M) VC với JavaScript hoặc IoC cho vấn đề đó.

Trước hết, bạn sẽ làm gì để kiểm tra? Nếu bạn chưa có, hãy kiểm tra các YUI Test video trong đó có một số thông tin tốt về thử nghiệm đơn vị với javascript.

Thứ hai, khi bạn nói "cách tốt nhất để dây lên tập hợp rằng:" Tôi có lẽ sẽ chỉ làm điều đó như một setter w/bộ điều khiển

// Production 
var cont = new NotebookController(); 
cont.setView(new NotebookView()); 

// Testing the View 
var cont = new NotebookController(); 
cont.setView(new MockNotebookView()); 

// Testing the Controller 
var cont = new MockNotebookController(); 
cont.setView(new NotebookView()); 

// Testing both 
var cont = new MockNotebookController(); 
cont.setView(new MockNotebookView()); 

Nhưng điều này làm cho một số giả định lớn vào cách bạn đã đã thiết kế bộ điều khiển của bạn và xem các đối tượng đã có.

2

Tôi có thể nói, chỉ cần dây chúng với nhau:

function wireTogether() { 
    var v = new View(); 
    var c = new Controller(); 
    c.setView(v); 
} 

Nhưng sau đó tất nhiên một câu hỏi khác đặt ra - làm thế nào để bạn kiểm tra) chức năng (wireTogether?

May mắn thay, JavaScript là một ngôn ngữ thực sự năng động, vì vậy bạn chỉ có thể gán giá trị mới để xem và điều khiển:

var ok = false; 

View.prototype.isOurMock = true; 
Controller.prototype.setView = function(v) { 
    ok = v.isOurMock; 
} 

wireTogether(); 

alert(ok ? "Test passed" : "Test failed"); 
3

Dependency Injection có lẽ là lựa chọn tốt nhất của bạn. So với Java, một số khía cạnh của việc này dễ thực hiện hơn trong mã JS, vì bạn có thể truyền một đối tượng đầy callbacks vào NotebookController của bạn. Các khía cạnh khác khó hơn, bởi vì bạn không có phân tích mã tĩnh để chính thức hóa giao diện giữa chúng.

3

Cảm ơn thông tin chi tiết.Tôi đã viết một tiện ích tiêm JavaScript phụ thuộc đơn giản. Sau khi tranh luận một lúc và nhận xét của bạn, điều đó đã xảy ra với tôi rằng DI thực sự là câu trả lời đúng bởi vì:

  1. Nó hoàn toàn tách biệt mối quan tâm của hệ thống dây điện từ logic nghiệp vụ trong khi vẫn giữ logic .
  2. Nó cho phép tôi cung cấp một cách tổng quát "gọi lại mọi thứ" trên các đối tượng của mình để có thể khởi tạo 3 giai đoạn: khởi tạo mọi thứ, kết nối tất cả mọi thứ. .
  3. Thật dễ dàng để kiểm tra các vấn đề thiếu phụ thuộc.

Vì vậy, đây là tiện ích DI:

var Dependency = function(_name, _instance, _dependencyMap) { 
    this.name = _name; 
    this.instance = _instance; 
    this.dependencyMap = _dependencyMap; 
} 

Dependency.prototype.toString = function() { 
    return this.name; 
} 

CONCORD.dependencyinjection = {}; 

CONCORD.dependencyinjection.Context = function() { 
    this.registry = {}; 
} 

CONCORD.dependencyinjection.Context.prototype = { 
    register : function(name, instance, dependencyMap) { 
     this.registry[name] = new Dependency(name, instance, dependencyMap); 
    }, 
    get : function(name) { 
     var dependency = this.registry[name]; 
     return dependency != null ? dependency.instance : null; 
    }, 

    init : function() { 
     YAHOO.log("Initializing Dependency Injection","info","CONCORD.dependencyinjection.Context"); 
     var registryKey; 
     var dependencyKey; 
     var dependency; 
     var afterDependenciesSet = []; 
     for (registryKey in this.registry) { 
      dependency = this.registry[registryKey]; 
      YAHOO.log("Initializing " + dependency.name,"debug","CONCORD.dependencyinjection.Context"); 

      for(dependencyKey in dependency.dependencyMap) { 
       var name = dependency.dependencyMap[dependencyKey]; 
       var instance = this.get(name); 
       if(instance == null) { 
        throw "Unsatisfied Dependency: "+dependency+"."+dependencyKey+" could not find instance for "+name; 
       } 
       dependency.instance[dependencyKey] = instance; 
      } 

      if(typeof dependency.instance['afterDependenciesSet'] != 'undefined') { 
       afterDependenciesSet.push(dependency); 
      } 
     } 

     var i; 
     for(i = 0; i < afterDependenciesSet.length; i++) { 
      afterDependenciesSet[i].instance.afterDependenciesSet(); 
     } 
    } 

} 
1

Tôi có một nghịch đảo của thư viện điều khiển cho javascript, tôi khá hài lòng với nó. https://github.com/fschwiet/jsfioc. Nó cũng hỗ trợ sự kiện, vì vậy nếu bạn muốn có một sự kiện khởi động tốt. Nó có thể sử dụng tài liệu hướng dẫn thêm ...

http://github.com/fschwiet/jsfioc

Một tùy chọn khác (mới hơn?), Trong đó có tài liệu tốt hơn và hỗ trợ, là requireJS (http://requirejs.org/).

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