<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>javascript 高级语法16-装饰者模式</title>
</head>
<body>
<script>
/*通过需求引出装饰者模式
*
*/ //接口
var Interface = function(name,methods){
if(arguments.length != 2){
alert("interface must have two paramters...");
}
this.name = name;//这个是接口的名字
this.methods = [];//定义个空数组来转载函数名
for (var i = 0; i < methods.length; i++) {
if(typeof methods[i] != "string"){
alert("method name must is String ...")
}else{
this.methods.push(methods[i])
}
}
}
//定义接口的一个静态方法来实现接口与实现类的直接检验
//静态方法不要写成Interface.prototype.* 因为这是写到接口原型连上的
//我们要把静态的函数直接写到类层次上
Interface.ensureImplements = function(object){
if(arguments.length<2){
alert("必须最少是2个参数");
return false;
}
//遍历
for (var i = 1; i < arguments.length; i++) {
var inter = arguments[i];
//如果你是接口就必须是Interface类型的
if(inter.constructor != Interface){
throw new Error("if is interface class must is Interface type");
}
//遍历函数集合并分析
for (var j = 0; j < inter.methods.length; j++) {
var method = inter.methods[j];
//实现类中必须有方法名字 和 接口中所有的方法名项目
if(!object[method] || typeof object[method] != "function"){
throw new Error("实现类并没有完全实现接口中的所有方法...");
}
}
}
} function demo(){
//汽车店的接口
var CarShop = new Interface("CarShop",["getPrice","assemble"]);
var myCarShop = function(){
this.getPrice = function(){
document.write(15000+"<br>");
}
this.assemble = function(){
document.write("汽车组装..."+"<br>")
}
Interface.ensureImplements(this,CarShop);
} var jimCarShop = new myCarShop();
jimCarShop.getPrice();
jimCarShop.assemble();
document.write("--------------------"+"<br>") /*新需求:
* 汽车还会有附属产品 音响 (k),真皮沙发(M),保险杠(N)
* 每一个附属的产品会影响到汽车的组装和其价格
* 你能想到什么办法?
*/ //改写接口
var CarShop2 = new Interface("CarShop2",["getPrice","assemble","addK","addM","addN"]);
var myCarShop2 = function(){
var price = 150000;
this.getPrice = function(){
document.write(price+"<br>")
}
this.assemble = function(){
document.write("汽车组装"+"<br>")
}
this.addK = function(){
price += 1000;
}
this.addM = function(){
price += 2000;
}
this.addN = function(){
price += 3000;
}
Interface.ensureImplements(this,CarShop2);
} var jimCarShop2 = new myCarShop2();
jimCarShop2.addK();
jimCarShop2.addM();
jimCarShop2.addN();
jimCarShop2.getPrice();
jimCarShop2.assemble(); /*好像能成功,但是新的问题来了
* 你把接口全改了,可是我继承本接口的类不一定全要有音响,沙发,保险杠。
* 难道我要改变所有实现本接口的实现类吗?
* 显然是不对的。
*/
//2.如果不改变接口,那我就增加子类
var CarShop = new Interface("CarShop",["getPrice","assemble"]);
var myCarShop = function(){
this.getPrice = function(){
document.write(150000+"<br>");
}
this.assemble = function(){
document.write("汽车组装..."+"<br>")
}
Interface.ensureImplements(this,CarShop);
}
var myCarShopM = function(){
this.getPrice = function(){
document.write(150100+"<br>");
}
this.assemble = function(){
document.write("汽车组装..."+"<br>")
}
Interface.ensureImplements(this,CarShop);
}
var myCarShopK = function(){
this.getPrice = function(){
document.write(150200+"<br>");
}
this.assemble = function(){
document.write("汽车组装..."+"<br>")
}
Interface.ensureImplements(this,CarShop);
}
//这种方式走不通
/*装饰者的概念和用法:
* 装饰者可以为对象添加新的特性
* 透明的把对象包装在具有相同接口的新对象中
*/ }
// demo();
function decorator(){
//装饰者模式来解决需求
var CarShop = new Interface("CarShop",["getPrice","assemble"]);
//目标对象
var myCarShop = function(){
this.getPrice = function(){
return 150000;
}
this.assemble = function(){
document.write("汽车组装...<br>");
}
Interface.ensureImplements(this,CarShop);
}
//装饰类
var M = function(carshop){
this.getPrice = function(){
return 1000 + carshop.getPrice();
}
this.assemble = function(){
document.write("M组装...<br>");
}
Interface.ensureImplements(this,CarShop);
}
var K = function(carshop){
this.getPrice = function(){
return 2000 + carshop.getPrice();
}
this.assemble = function(){
document.write("k组装...<br>");
}
Interface.ensureImplements(this,CarShop);
}
var N = function(carshop){
this.getPrice = function(){
return 3000 + carshop.getPrice();
}
this.assemble = function(){
document.write("N组装...<br>");
}
Interface.ensureImplements(this,CarShop);
} //调用 var car =new K(new M(new myCarShop()));
alert(car.getPrice());
car.assemble();
}
decorator();
</script>
</body>
</html>

JavaScript设计模式-16.装饰者模式(上)的更多相关文章

  1. 再起航,我的学习笔记之JavaScript设计模式13(装饰者模式)

    装饰者模式 装饰者模式(Decorator): 在不改变原对象的基础上,通过对其进行过包装拓展(添加属性高或者方法)使原有对象可以满足用户的更复杂需求. 如果现在我们有个需求,需要做一个提交表单,当我 ...

  2. Javascript设计模式之装饰者模式详解篇

    一.前言: 装饰者模式(Decorator Pattern):在不改变原类和继承的情况下动态扩展对象功能,通过包装一个对象来实现一个新的具有原对象相同接口的新的对象. 装饰者模式的特点: 1. 在不改 ...

  3. JavaScript设计模式-17.装饰者模式(下)

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. JavaScript设计模式(装饰者模式)

    一.模拟传统面向对象语言的装饰者模式: 假设我们在编写一个飞机大战的游戏,随着经验值的增加,我们操作的飞机对象可以升级成更厉害的飞机,一开始这些飞机只能发射普通的子弹,升到第二级时可以发射导弹,升到第 ...

  5. JavaScript设计模式(8)-装饰者模式

    装饰者模式 1. 作用: 可用来透明地把对象包装在具有同样接口的另一对象之中,这样可以给一个方法添加一些行为,然后将方法调用传递给原始对象. 可用于为对象增加功能,用来代替大量子类. 装饰者对其组件进 ...

  6. javascript设计模式之装饰者模式

    /* * 装饰者模式提供比继承更有弹性的替代方案 * 在不改变原构造函数的情况下,添加新的属性或功能 */ //需要装饰的类(函数) function Macbook() { this.cost = ...

  7. 学习javascript设计模式之装饰者模式

    1.装饰者模式定义:给对象动态添加职责的方式称为装饰者(decorator)模式. js如何实现装饰者模式 通过保存原函数引用方式改写某函数 window.onload = function(){al ...

  8. 再起航,我的学习笔记之JavaScript设计模式16(享元模式)

    ### 享元模式 **享元模式(Flyweight):** 运用共享技术有效地支持大量的细粒度的对象,避免对象间拥有相同内容造成多余的开销. 上回我们在组合模式中创建了文章列表类,这次我们要向不同的文 ...

  9. javascript设计模式--策略模式

    javascript策略模式总结 1.什么是策略模式? 策略模式的定义是:定义一系列的算法,把他们独立封装起来,并且可以相互替换. 例如我们需要写一段代码来计算员工的奖金.当绩效为a时,奖金为工资的5 ...

随机推荐

  1. 将Socket应用程序从Unix向Windows移植中应注意的几点问题

    套接字(socket)当今已成为最流行的网络通信应用程序接口.套接字最初是由加利福尼亚大学Berkeley分校为Unix操作系统开发的网络通信接口,后来它又被移植到DOS与Windows系统,特别是近 ...

  2. 安装Greenplum-perfmon-web监控软件遇到的问题及解决

    环境 Product Version Pivotal Greenplum (GPDB) 4.3.x Pivotal Greenplum Command Center (GPCC)   Others   ...

  3. Async 和 Await 的异步编程 资料汇总

    使用 Async 和 Await 的异步编程 https://msdn.microsoft.com/zh-cn/library/hh191443(v=vs.120).aspx 异步程序中的控制流 ht ...

  4. 自己从0开始学习Unity的笔记 VII (C#中类继承练习)

    好久都没有写了.今天做了类继承的练习,做了一个小队,进行简单的判定. namespace 兵团建立练习 { class ServantBasics { public string name; //pr ...

  5. 基于ASP.NET生成二维码详细源码

    详细链接:https://shop499704308.taobao.com/?spm=a1z38n.10677092.card.11.594c1debsAGeakusing System; using ...

  6. 构造函数(JAVA)

    构造函数 :是一种特殊的方法,主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中. 特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类 ...

  7. Exp3 免杀原理与实践 20164323段钊阳

    网络对抗技术 20164323 Exp3 免杀原理与实践 免杀 一般是对恶意软件做处理,让它不被杀毒软件所检测.也是渗透测试中需要使用到的技术. 要做好免杀,就时清楚杀毒软件(恶意软件检测工具)是如何 ...

  8. ClamAV资料链接

    1.http://wiki.ubuntu.org.cn/index.php?title=ClamAV&variant=zh-cn Ubuntu的wiki下对ClamAV的大致介绍,包括使用. ...

  9. mysql主从报错截图

    1.首先确认报错的binlog和last event. 2.然后去主的机器上查看该报错的内容和报错的的位置,如果是结尾报错的,可以直接从新的binlog进行同步. #/mysql/logs# ../b ...

  10. 阿里云ros实例

    模板文件 { "ROSTemplateFormatVersion": "2015-09-01", "Parameters": { " ...