我正在开发(并且实际上已经完成)一个根据用户输入的数据获取报价的项目。我已经编写了代码并且运行良好。它是使用事件和函数用 javascript/jQuery 编写的,更像是这样的(我刚刚为这个问题编写的示例,而不是实际的代码):
// event - when the quantity field changes
$('input[name=quantity]').change(function(){
// get the product
var product = $('input[name=product]').val();
// run function to set the base price
setBasePrice(this.value,product);
});
// function - set the base price
function setBasePrice(quantity,product){
var basePrice = quantity * getTierPrice(quantity,product);
// show the base price to user
$('.basePrice').empty().val(basePrice);
};
// function - set price based on quantity and product
function getTierPrice(quantity,product){
// switches through 6 tiers (based on quantity)
// e.g. - If product is x and quantity is y, price = z
// returns a value
};
还有更多的工作部分,但我编写它是为了说明它是如何组合在一起的。它看起来真的很冗长并且有很多移动的部分。到了更新的时候,就很痛苦了。
但我想知道我是否应该使用 OOP 来做这样的事情?我真的只是想深入了解 javascript 最佳实践的根源,并找出这样的东西应该如何真正组合在一起。我觉得我写的很多代码虽然有效,但并不总是最好的方法,也许是因为我是自学的,还没有真正深入挖掘。
如果有助于理解正在发生的事情,我将其功能分成几部分。对你来说理解每一个部分是如何工作的并不重要:
Things I'm expecting
= zip code (number)
= product (string)
= quantity (number)
- Need to verify number is between x and y (e.g. - 100 to 10000)
= artwork colors (number)
- Need to verify number is between x and y (e.g. - 0 to 6)
Things I'm calculating
= base price (number)
- Depends on the product selected
- Depends on the quantity entered (6 tiers of pricing based on quantity)
e.g. - "Product 1" quantity of 101 to 200 = $9, quantity of 201 to 300 = $7, etc
= screen charge (number)
- Depends on the number of artwork colors entered
- Depends on the quantity entered (uses same tier as when calculating base price)
e.g. - "Product 1" quantity of 101 to 200 add 1.00 per artwork color
- Gets rolled into the base price
e.g. - base price = base price + (artwork colors*quantity);
= shipping cost (hits url via ajax to fetch rate, returns number)
- Depends on zip code entered
- Depends on product selected (each product has different weight)
Things I need to output
= final price
= shipping cost
= base price
所以我应该使用 OOP,我应该看看 YUI 模块模式?如果是这样,在高层次上,我将如何开始?我不需要完整的代码示例,只需要知道从哪里开始。我真的希望我的代码看起来不错并且结构正确。非常感谢任何建议、资源链接等。
I'm working on (and have actually finished) a project that fetches price quotes based on user-entered data. I've written the code already and it works fine. It's written in javascript/jQuery using events and functions, more like this (example I just wrote for this question, not actual code):
// event - when the quantity field changes
$('input[name=quantity]').change(function(){
// get the product
var product = $('input[name=product]').val();
// run function to set the base price
setBasePrice(this.value,product);
});
// function - set the base price
function setBasePrice(quantity,product){
var basePrice = quantity * getTierPrice(quantity,product);
// show the base price to user
$('.basePrice').empty().val(basePrice);
};
// function - set price based on quantity and product
function getTierPrice(quantity,product){
// switches through 6 tiers (based on quantity)
// e.g. - If product is x and quantity is y, price = z
// returns a value
};
There are many more working parts but I wrote that to illustrate how it's put together. It just seems really verbose and a lot of moving parts. When it comes time to update it, it's a pain.
But I'm wondering if I should be using OOP for something like this? I really just want to get to the root of javascript best practice and find out how something like this should really be put together. I feel like a lot of the code I write, although works, isn't always the best way, maybe it's because I am self taught and haven't really dug in deep enough.
I broke the functionality into pieces if it helps to understand what is going on. It's not crucial for you to understand how every bit works:
Things I'm expecting
= zip code (number)
= product (string)
= quantity (number)
- Need to verify number is between x and y (e.g. - 100 to 10000)
= artwork colors (number)
- Need to verify number is between x and y (e.g. - 0 to 6)
Things I'm calculating
= base price (number)
- Depends on the product selected
- Depends on the quantity entered (6 tiers of pricing based on quantity)
e.g. - "Product 1" quantity of 101 to 200 = $9, quantity of 201 to 300 = $7, etc
= screen charge (number)
- Depends on the number of artwork colors entered
- Depends on the quantity entered (uses same tier as when calculating base price)
e.g. - "Product 1" quantity of 101 to 200 add 1.00 per artwork color
- Gets rolled into the base price
e.g. - base price = base price + (artwork colors*quantity);
= shipping cost (hits url via ajax to fetch rate, returns number)
- Depends on zip code entered
- Depends on product selected (each product has different weight)
Things I need to output
= final price
= shipping cost
= base price
So should I be using OOP, should I look at the YUI Module Pattern? If so, at a high level, how would I start? I don't need a full code sample, just an idea of where to begin. I really want my code to look good and be structured properly. Any advice, resource links, etc is greatly appreciated.
发布评论
评论(5)
我对“我是否应该将这块自由浮动函数放入类的一组方法中”(适用于任何语言,而不仅仅是 JS)的一般测试很简单:我是否在各处传递相同的变量?
如果是这样,我认为将这些变量放入类的字段中,然后将这些函数放入方法中是有帮助的,因为这样所有这些方法都可以引用所有这些变量,而不必“通过”传递所有内容手”。此外,您可以通过这种方式更好地控制事情。
例如,假设您有几个函数接受“foo”参数并对其调用“setBar”,然后在其上设置“dirty”标志。通过这种设置,很容易意外忘记设置“脏”标志。但是,通过将 foo 设置为字段并创建 setFooBar 方法(调用“setBar”并设置“dirty”标志),您可以确保始终设置“dirty”标志。
无论如何,我无法从您提供的有限代码示例中判断您的代码是否通过测试,但希望这能给您带来一些思考。
My general test for "should I make this chunk of free floating functions in to a set of methods on a class" (which applies to any language, not just JS), is simple: am I passing the same variables around all over the place?
If so, I think it helps matters to make those variables in to fields of a class, and then make those functions in to methods, because then all of those methods can reference all of those variables, without you having to pass everything around "by hand". Furthermore, you can control things much better this way.
For instance, let's say you have several functions that takes a "foo" argument and call "setBar" on it, then set a "dirty" flag on it. With that setup, it's easy to accidentally forget to set the "dirty" flag. However, by making foo a field, and creating a setFooBar method (which calls "setBar" and sets the "dirty" flag), you can ensure that the "dirty" flag always gets set.
Anyhow, I can't tell from the limited code examples you've provided whether your code passes the test, but hopefully this gives you some food for thought.
您可以做的是研究 MVC 范式 - 逻辑的架构分离,旨在将代码的组件抽象为模型、视图和控制器。它在后端语言框架中最为人所知(用于 PHP 的 CakePHP、用于 Ruby 的 Rails、用于 Python 的 Django 等),但绝对也适用于 JS。
请参阅这篇文章以获取一些方便的参考。就我个人而言, Backbone 似乎是一个简单的轻量级起点(并且它支持 jQuery(如我也看到你提到了))。
What you could do, is look into the MVC-paradigm - an architectural separation of logic that aims to abstract your code's components into Models, Views and Controllers. It's mostly known in frameworks for backend-languages (CakePHP for PHP, Rails for Ruby, Django for Python etc.), but is absolutely also applicable to JS.
See this post for some handy references. Personally, Backbone seems like an easy light-weight place to start off (and it supports jQuery (as I saw you referred too)).
所有只能通过函数脚本完成的 javascript 工作都可以通过 oop 脚本完成,反之亦然。
在大多数情况下,使用 javascript 作为 OOP 语言更优雅、更强大,但不一定更高效。
当我开始将 javascript OOP 基础知识放在一起时,我对原型继承非常着迷,以至于我到处都使用对象......直到我意识到我使一切变得复杂(例如:而不是普通的 2 行图像预加载器脚本,我开始编码 ImgObjects,这比我原来的任务所需的要复杂得多)。
从您提供的小代码中,我无法真正判断 OOP 是否会给您的项目带来重大改进,但我建议您在原型继承方面达到顶峰,并可能采用一些设计模式(这本书太棒了),但不要忘记 javascript 是一种全函数式语言!
All the javascript work you can do only by functional scripting can be done by oop scripting and vice versa.
In most cases, using javascript as an OOP language is more elegant and powerfull, but not necessarily more efficient.
When I started to put toghether the javascript OOP basics , I was so fascinated by the prototipical inheritance , that i used objects everywere... until I realized that I was complicating everything (ex: instead of a normal 2-line image preloader script, I started coding ImgObjects that were much more complex than my original task required).
From the little code you provided, I can't really tell if OOP would bring major improvements on your project, but i suggest you take a peak at prototipal inheritance and maby some design patterns (this book is amazing), but don't forget that javascript is a fully functional language!
我总是提倡哎哟!我认为 javascript 作为 oop 语言工作得很好。 o'reilly 有一本名为“javascript 模式”的书。它是由一位名叫 stoyan stefanov 的雅虎大师编写的,它非常擅长解释何时在 js 中使用 oop,以及如何以良好的方式使用它。
根据这本书,我认为你会创建一个对象,它有一个构造函数来获取输入数据,验证它,然后保存到成员。那么它将有一些方法来执行您所写的计算。这些计算将在对象创建期间存储的成员的帮助下进行。
这是一个示例类:
上面构建信息的方式是构建 oop 项目的非常好的文档基础。我认为它看起来有点像一个类。我的意思是,您记录的模型似乎很适合我这里的小代码示例。
i always promote oop! i think javascript works quite ok as oop language. there's a book called "javascript patterns" from o'reilly. it's written by some yahoo guru named stoyan stefanov, and it's very good at explaining when to use oop in js, and how to do it in a good way.
according to this book, i think that you would make an object that has a constructor taking your input data, validating it, and then saving to members. then it would have some methods for performing the calculations you write about. and those calculations would be made with the help of the members stored during object creation.
here's an example class:
the way you structure information above is a very good basis of documentation to build an oop project upon. and it sort of looks like a class i think. what i'm saying is that it seems as though your documented model would fit right into my little code example here.
与重构相比,我更不用担心 OOP 与非 OOP - 例如,如果您有非常相似的“setBasePrice”和“setXXX”和“setYYY”,则应该将它们转换为通用的“setAnything()”调用。 OOP 可能有助于完成该任务,但并不重要
I would worry less about OOP verses non-OOP than with refactoring - e.g. if you have "setBasePrice" and "setXXX" and "setYYY" that are very similar, you should convert them to a generic "setAnything()" call. OOP might help in that task but is not vital to it