<!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. npm是干什么的?

    允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用. 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用. 其实npm ...

  2. Receiving Transaction Processor Conundrum

    what would we do if we are faced with a situation to execute a receiving transaction in oracle ebusi ...

  3. AndroidStudio-Unable to save settings Failed to save settings. Please restart Android Studio

    Unable to save settings Failed to save settings. Please restart Android Studio 解决方法: 删除工程的.idea 然后在 ...

  4. Unity&C# SingerMonoManager泛型单例

    管理各种管理器 ///为什么需要单例 ///单例模式核心在于对于某个单例类,在系统中同时只存在唯一一个实例,并且该实例容易被外界所访问: ///避免创建过多的对象,意味着在内存中,只存在一个实例,减少 ...

  5. Cesium开发实践汇总

    一.简介.开发环境搭建 二.Viewer控件 三.地图图层介绍 四.地形介绍 五.坐标变换 六.CZML 七.3D模型

  6. WPF:MVVM模式下ViewModel关闭View

    不外乎两种基本方法. 消息通知和参数传递. 一.消息通知 利用View里的IsEnable属性 原理是这样的: 1.UI中的IsEnabled绑定VM中的属性 2.UI的后台代码中,注册IsEnabl ...

  7. C# BackgroundWorker 的使用、封装

    示例代码: PT_USER_INFO user = new PT_USER_INFO(); IList<TES_COMBAT_TASK> taskList = new List<TE ...

  8. Polynomial ( Arithmetic and Algebra) CGAL 4.13 -User Manual

    1 Fundamentals A polynomial is either zero, or can be written as the sum of one or more non-zero ter ...

  9. sqlserver排名函数

    在做开发的时候,排名函数是sqlserver经常用到的函数,在分页的时候需要用,分组的时候也要用,主要排名函数有row-number,rank(),dense-rank(),NTILE()接下来详细说 ...

  10. Python3.5 学习三

    对文件的操作 打开模式: 1 f=open("xxx","r",encoding=="utf-8") 只读 2 f=open("x ...