function Event(name) {
var handlers = [];
this.getName = function () {
반환 이름;
};
this.addHandler = 함수(핸들러) {
handlers.push(handler);
};
this.removeHandler = function(handler) {
for (var i = 0; i < handlers.length; i ) {
if (handlers[i] == handler) {
handlers.splice(i, 1);
휴식;
}
}
};
this.fire = function (eventArgs) {
handlers.forEach(function (h) {
h(eventArgs);
});
};
}
function EventAggregator() {
var events = [];
function getEvent(eventName) {
return $.grep(events, function (event) {
return event.getName() === eventName;
})[0];
}
this.publish = function(eventName, eventArgs) {
var event = getEvent(eventName);
if (!event) {
event = new Event(eventName);
events.push(이벤트);
}
event.fire(eventArgs);
};
this.subscribe = function(eventName, handler) {
var event = getEvent(eventName);
if (!event) {
event = new Event(eventName);
events.push(이벤트);
}
event.addHandler(핸들러);
};
}
然后,我们来声ming제품对象,代码如下:
function Product(id, Description) {
this.getId = function () {
return id;
};
this.getDescription = function () {
설명 반환;
};
}
장바구니에 추가된 항목 추가 기능이 있습니다.去。
function Cart(eventAggregator) {
var items = [];
this.addItem = 함수(항목) {
items.push(항목);
eventAggregator.publish("itemAdded", item);
};
}
CartController主要是接受cart对象和事件聚合器,通过订阅itemAdded来增加一个li元素节点,通过订阅productSelected事件来添加제품。
function CartController(cart, eventAggregator) {
eventAggregator.subscribe("itemAdded", function (eventArgs) {
var newItem = $('
').html(eventArgs.getDescription()).attr('id-cart', eventArgs.getId()).appendTo ("#카트")
});
eventAggregator.subscribe("productSelected", function (eventArgs) {
cart.addItem(eventArgs.product);
});
}
저장소에 있는 目为了获取数据(可以从ajax里获取), 然后暴露get数据적 방법。
function ProductRepository() {
var products = [new Product(1, "Star Wars Lego Ship"),
신제품(2, "바비인형"),
신제품(3, "원격조종비행기")];
this.getProducts = function () {
제품 반품;
}
}
ProductController리정义了一个onProductSelect방법,主要是发布触发productSelected事件,forEach要是用于绑定数据到产products列表上代,码아래:
function ProductController(eventAggregator, productRepository) {
var products = productRepository.getProducts();
function onProductSelected() {
var productId = $(this).attr('id');
var product = $.grep(products, function (x) {
return x.getId() == productId;
})[0];
eventAggregator.publish("productSelected", {
제품: 제품
});
}
products.forEach(function (제품) {
var newItem = $('
').html(product.getDescription())
.attr('id', product.getId())
.dblclick(onProductSelected)
.appendTo("#products")
});
}
最后声明匿name函数:
(함수 () {
var eventAggregator = new EventAggregator(),
cart = new Cart(eventAggregator),
cartController = new CartController(cart, eventAggregator),
productRepository = new ProductRepository(),
productController = new ProductController(eventAggregator, productRepository);
})();
익명 함수의 코드가 줄어든 것을 볼 수 있습니다. 주로 객체의 인스턴스화 코드입니다. 코드에서는 정보를 받아 액션에 전달하는 컨트롤러의 개념도 소개했습니다. 또한 주로 표시를 처리하는 데 사용됩니다. 제품 리팩토링의 결과는 객체 선언을 많이 작성하게 되지만, 각 객체에는 표시 데이터가 표시되어야 하고, 컬렉션을 처리하려면 처리 컬렉션이 변경되어야 한다는 장점이 있습니다. 결합도가 매우 낮습니다.
최종 코드
함수 이벤트(이름) {
var handlers = [];
this.getName = function () {
return name
}; (핸들러) {
handlers.push(handler)
};
this.removeHandler = function (handler) {
for (var i = 0; i < handlers.length ; i ) {
if (handlers[i] == handler) {
handlers.splice(i, 1)
break
}
; >
this.fire = function (eventArgs) {
handlers.forEach(function (h) {
h(eventArgs);
})
}
function EventAggregator() {
var events = [];
function getEvent(eventName) {
return $.grep(events, function (event) {
return 이벤트 .getName( ) === eventName;
})[0];
this.publish = function (eventName, eventArgs) {
var event = getEvent(eventName);
if (!event) {
event = new Event(eventName)
events.push(event)
}
event.fire(eventArgs); };
this.subscribe = function(eventName, handler) {
var event = getEvent(eventName)
if (!event) {
event = new Event( eventName);
events.push(event);
event.addHandler(handler)
}
function Product(id, 설명) {
this.getId = function() {
return id;
};
this.getDescription = function() {
return 설명; }
function Cart(eventAggregator) {
var items = [];
this.addItem = function(item) {
items.push(item)
eventAggregator.publish("itemAdded", 항목);
};
}
function CartController(cart, eventAggregator) {
eventAggregator.subscribe("itemAdded", function (eventArgs) {
var newItem = $('
').html(eventArgs.getDescription()).attr('id-cart', eventArgs.getId()).appendTo("#cart ");
});
eventAggregator.subscribe("productSelected", function (eventArgs) {
cart.addItem(eventArgs.product);
});
}
function ProductRepository() {
var products = [new Product(1, "스타워즈 레고 선박"),
new Product(2, "Barbie Doll"),
new Product (3, "원격 제어 비행기")];
this.getProducts = function () {
return products;
}
}
function ProductController(eventAggregator, productRepository) {
var products = productRepository.getProducts();
function onProductSelected() {
var productId = $(this).attr('id')
var product = $.grep (제품, 함수 (x) {
return x.getId() == productId;
})[0];
eventAggregator.publish("productSelected", {
제품: product
})
}
products.forEach(function (product) {
var newItem = $('').html(product .getDescription( ))
.attr('id', product.getId())
.dblclick(onProductSelected)
.appendTo("#products")
}); }
(function () {
var eventAggregator = new EventAggregator(),
cart = new Cart(eventAggregator),
cartController = new CartController(cart, eventAggregator),
productRepository = new ProductRepository(),
productController = new ProductController(eventAggregator, productRepository);
})();
요약
이 리팩토링 결과를 보고 싶어하는 블로거도 있을 것입니다. 내가 물었더니, 꼭 그렇게 복잡하게 만들 필요가 있나요? 제가 말할 수 있는 것은 이 작업을 수행해야 하는지 여부는 프로젝트 상황에 따라 다르다는 것입니다.
프로젝트가 아주 작은 프로젝트이고 코드가 많지 않다면 사실 그렇게 복잡하게 리팩토링할 필요는 없지만, 프로젝트가 매우 복잡한 대규모 프로젝트이거나 소규모 프로젝트라면 프로젝트가 미래에 매우 빠르게 성장할 경우 향후 유지 관리를 용이하게 하기 위해 초기 단계에서 책임 분리에 대한 SRP 원칙을 고려해야 합니다.