[Decode error - output not utf-8]
-----------------------------
购物清单 方便面 : 100 x 50 = 5000 | 4000
菊花茶 : 10 x 50 = 500 | 500
-----------------------------
优惠使用 : 国庆1折优惠
购物合计 4500 -> 450 [Finished in 0.6s]

首先封装收银机类,怎么把商品设进,怎么把收银金额输出。

然后封装商品,和金额独立

然后进行收银策略编写。打折,满返针对的是最后的结果。

收银机添加设置策略接口,调用原生金额接口,调用策略接口,获得策略后金额接口

下个需求到商品的具体折扣,譬如买几送几

封装策略到商品处,商品创建的时候根据自己的名字到工厂去领取自己的“福利”

后续还想实施,组合折扣,譬如买牙膏同时买牙刷,减5块钱

架构要大改了(・-・*) ,暂时搁置

/**
* by JackChen 2016-3-15 19.20.01
* 看完马士兵老师策略模式后作业
*
* 原文是讲解comparable接口 和 compareTo
*
* 所有实现了comparable接口的类都可以用于比较。
*
* 而更高级的是,我不同场景需要不同的比较时,通过定制本类的比较器,
* 借用比较器的compareTo,得到不同的比较结果
*
* 已实现
* 1. 单个物品多个数量
* 2. 多个物品多个数量
* 3. 多个物品结算打印
* 4. 多个物品总金额折扣策略(几折、满返)
* 5. 单个物品优惠策略(多少个送多少个)
*
* 待实现
* 6. 单个物品 买多个送多个 跟购物物品无关
* 7. 组合购买
*/ ////////////////////////////////////////////////////////////////////////
/// 收银策略类 //普通收钱
var NormalStrategy = function() {
var self = this;
self.type = "total";
self.description = "没有使用优惠";
};
NormalStrategy.prototype = {};
NormalStrategy.prototype.constructor = NormalStrategy;
NormalStrategy.prototype.desc = function() {
return this.description;
};
NormalStrategy.prototype.discount = function(money) {
return money;
}; //折扣策略
var PrecentOffStrategy = function(description, precent) {
var self = this;
self.type = "total";
self.precent = precent;
self.description = description + (precent*10) + "折优惠";
};
PrecentOffStrategy.prototype = new NormalStrategy();
PrecentOffStrategy.prototype.constructor = PrecentOffStrategy;
PrecentOffStrategy.prototype.desc = function() {
return this.description;
};
PrecentOffStrategy.prototype.discount = function(money) {
return money * this.precent;
}; //满返策略
var GivebackStrategy = function(description, enough, giveback) {
var self = this;
self.type = "total";
self.enough = enough;
self.giveback = giveback;
self.description = description + "满"+ enough + "返" + giveback + "优惠";
};
GivebackStrategy.prototype = new NormalStrategy();
GivebackStrategy.prototype.constructor = GivebackStrategy;
GivebackStrategy.prototype.desc = function() {
return this.description;
};
GivebackStrategy.prototype.discount = function(money) {
if (money >= this.enough) {
money -= this.giveback;
};
return money;
}; ////////////////////////////////////////////////////////////////////////
/// 销售品种折扣工厂 var SaleItemStrategyFactory = function() {
};
SaleItemStrategyFactory.prototype = {};
SaleItemStrategyFactory.prototype.constructor = SaleItemStrategyFactory;
SaleItemStrategyFactory.prototype.getInstance = function(name) {
var self = this;
var strategy = null; switch (name) {
case "方便面":
strategy = new BuyMoreStrategy("特惠",4,1);
break;
default:
// statements_def
break;
} return strategy;
}; //普通
var ItemNormalStrategy = function() {
var self = this;
self.type = "total";
self.description = "没有优惠";
};
ItemNormalStrategy.prototype = {};
ItemNormalStrategy.prototype.constructor = ItemNormalStrategy;
ItemNormalStrategy.prototype.desc = function() {
return this.description;
};
ItemNormalStrategy.prototype.discount = function(money) {
return money;
}; //买几送几
var BuyMoreStrategy = function(description, buy, free) {
var self = this;
self.type = "total";
self.buy = buy;
self.free = free;
self.description = description + "买"+ buy + "送" + free;
};
BuyMoreStrategy.prototype = new ItemNormalStrategy();
BuyMoreStrategy.prototype.constructor = BuyMoreStrategy;
BuyMoreStrategy.prototype.desc = function() {
return this.description;
};
BuyMoreStrategy.prototype.discount = function(item) {
var give = item.num / (this.buy + this.free);
var left = item.num % (this.buy + this.free);
money = (give* this.buy + left)*item.price;
return money;
}; ////////////////////////////////////////////////////////////////////////
/// 销售品种 var SaleItem = function(name , price) {
var self = this;
self.name = name;
self.price = price;
self.num = 1;
self.strategy = factory.getInstance(self.name);
};
SaleItem.prototype = {};
SaleItem.prototype.constructor = SaleItem;
SaleItem.prototype.clone = function() {
var self = this;
var cloneItem = new SaleItem();
cloneItem.name = self.name;
cloneItem.price = self.price;
cloneItem.num = self.num;
cloneItem.strategy = self.strategy;
return cloneItem;
};
SaleItem.prototype.count = function() {
return this.price * this.num;
};
SaleItem.prototype.discountProcess = function(money) {
if (this.strategy) {
money = this.strategy.discount(this);
};
return money;
};
SaleItem.prototype.discount = function() {
return this.discountProcess(this.count());
}; ////////////////////////////////////////////////////////////////////////
/// 收银策略类 var CashRegister = function() {
var self = this;
self.totalDiscountStrategy = new NormalStrategy();
self.arr = [];
};
CashRegister.prototype = {};
CashRegister.prototype.constructor = CashRegister; //添加商品
CashRegister.prototype.add = function(item, num) {
var self = this;
if (num) {
item.num = num;
}; self.arr.push(item);
};
//添加折扣策略
CashRegister.prototype.setTotalDiscountStrategy = function(strategy) {
this.totalDiscountStrategy = strategy;
}; //总计金额
CashRegister.prototype.count = function() {
var self = this;
var totalMoney = 0;
self.arr.forEach( function(item, index) {
totalMoney += item.discount();
});
return totalMoney;
};
//折扣加入
CashRegister.prototype.discountProcess = function(money) {
var self = this;
if (self.totalDiscountStrategy) {
money = self.totalDiscountStrategy.discount(money);
};
return money;
};
//折后金额
CashRegister.prototype.discount = function() {
var self = this;
var totalMoney = self.count();
return self.discountProcess( totalMoney );
}; //结算清单
CashRegister.prototype.print = function() {
var self = this;
console.log('-----------------------------');
console.log(' 购物清单 ');
console.log(''); var totalMoney = 0;
self.arr.forEach(function(item, index) {
console.log(" %s : %s x %s = %s | ",item.name, item.price, item.num, item.count(),item.discount());
}); console.log('-----------------------------');
console.log(' 优惠使用 : ' + self.totalDiscountStrategy.desc())
console.log(' 购物合计 ' + self.count() +" -> "+ self.discount() );
console.log('');
}; ////////////////////////////////////////////////////////////////////////
/// 测试类 var factory = new SaleItemStrategyFactory(); var cashRegister = new CashRegister();
cashRegister.setTotalDiscountStrategy(new PrecentOffStrategy("国庆",0.1));
// cashRegister.setTotalDiscountStrategy(new GivebackStrategy("劳动节",500,300));
// cashRegister.setTotalDiscountStrategy(new GivebackStrategy("劳动节",1000,500)); cashRegister.add(new SaleItem("方便面",100),50);
cashRegister.add(new SaleItem("菊花茶",10),50); cashRegister.print();

javascript 写策略模式,商场收银打折优惠策略的更多相关文章

  1. [Python设计模式] 第2章 商场收银软件——策略模式

    github地址: https://github.com/cheesezh/python_design_patterns 题目 设计一个控制台程序, 模拟商场收银软件,根据客户购买商品的单价和数量,计 ...

  2. php 商场收银收费系统,使用的策略模式

    <?php//策略模式就是你有很多的方法,选择一种适合自己的,// 单例模式就是只有一个实例对象,不需要每个文件都要加载,比如连接数据库,// 工厂模式就是 //策略模式 优惠系统.工资计算系统 ...

  3. 读《大话设计模式》——应用工厂模式的"商场收银系统"(WinForm)

    要做的是一个商场收银软件,营业员根据客户购买商品单价和数量,向客户收费.两个文本框,输入单价和数量,再用个列表框来记录商品的合计,最终用一个按钮来算出总额就可以了,还需要一个重置按钮来重新开始. 核心 ...

  4. 在商城系统中使用设计模式----策略模式之在spring中使用策略模式

    1.前言: 这是策略模式在spring中的使用,对策略模式不了解对同学可以移步在商城中简单对使用策略模式. 2.问题: 在策略模式中,我们创建表示各种策略的对象和一个行为,随着策略对象改变而改变的 c ...

  5. 智能ERP收银统计-优惠统计计算规则

    1.报表统计->收银统计->优惠统计规则          第三方平台优惠:(堂食订单:支付宝口碑券优惠)+(外卖订单:商家承担优惠)          自平台优惠:(堂食订单:商家后台优 ...

  6. 读《大话设计模式》——应用策略模式的"商场收银系统"(WinForm)

    策略模式的结构 这个模式涉及到三个角色: 环境(Context)角色:持有一个 Strategy 类的引用.抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现.此角色给出所 ...

  7. javascript 写状态模式

    写了状态模式的切换,以及分支循环.but 怎么实现子状态嵌套呢? /** * by JackChen 2016-3-26 11.51.20 * * 状态模式: * 一个状态到另一个状态的变换.其实可以 ...

  8. JavaScript设计模式之策略模式(学习笔记)

    在网上搜索“为什么MVC不是一种设计模式呢?”其中有解答:MVC其实是三个经典设计模式的演变:观察者模式(Observer).策略模式(Strategy).组合模式(Composite).所以我今天选 ...

  9. 商场促销-策略模式(和简单工厂模式很像的哇) C#

    还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 废话不多说,直接进入正题: 首先按照大话设计模式的解释,在这里也总结下策略模式 ...

随机推荐

  1. 【腾讯优测干货分享】如何降低App的待机内存(五)——优化dex相关内存及本章总结

    本文来自于腾讯优测公众号(wxutest),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/01Abwe0p1h3WLh28Tzg_Dw 1.5案例:优化dex相 ...

  2. 【三支火把】---C文件学习

    ---恢复内容开始--- 又看了一遍文件的知识点了,断断续续已经看了2-3遍,也就这次花了点时间做了一下总结,以后我想都不会再去翻书了,哈哈. 1. 基于缓冲区的文件操作2. 打开关闭文件3. 单个字 ...

  3. eclipse项目出现红色叉叉解决方案

    方法一:导入的文件被删除了.解决方法:右击项目名,在弹出的菜单中选择“Bulid Path”-->“configure build path”-->“Source”,找到已被删除的那个文件 ...

  4. jquery如何让滚动条默认在最底部

    $(document).ready(function() { $("#content").scrollTop($("#content")[0].offsetHe ...

  5. Linux系列:Ubuntu虚拟机设置固定IP上网(配置IP、网关、DNS、防止resolv.conf被重写)

    虚拟机里设置上网方式为NAT最方便,因为无需手动设置即可上网,但是NAT的上网方式默认是DHCP动态分配IP的,这意味着你每次重启虚拟机都 有不一样的IP地址,这对一般用户没任何问题.但是如果你的机子 ...

  6. Android开发_Gson解析

    //转换器 GsonBuilder builder = new GsonBuilder(); // 不转换没有 @Expose 注解的字段 builder.excludeFieldsWithoutEx ...

  7. C++实现建立和一二进制树的三个递归遍历

    说明:这篇文章是学习交流,转载请注明出处,欢迎转载! 二叉树是一种常见的数据结构.二叉树的遍历也是家常便饭的事了,这里仅仅写出一个完整的能够执行的C++代码来随便建立一个例如以下图所看到的的二叉树,建 ...

  8. lambda显式声明返回值

    10.21 编写一个lambda,捕获一个局部int变量,并递减变量值,直至它变为0.一旦变量变为0,再调用lambda应该不再递减变量.lambda应该返回一个bool值,指出捕获的变量是否为0. ...

  9. C# #define

    https://msdn.microsoft.com/library/yt3yck0x.aspx 使用 #define 定义符号.当您将符号用作传递给 #if 指令的表达式时,此表达式的计算结果为 t ...

  10. 动作-CCActionInterval之CCAnimation&CCAnimate

    动画简单实例 v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#def ...