【JSOO】设计模式
- 单例模式
- 工厂模式
- 状态模式
- 观察者模式
- 桥接模式
设计模式(是一种通过经验中总结出来的经过反复验证能够解决一类通用问题的可以反复重用的就可称它为模式,否则只能称为功能模块);模式:把解决问题的方法抽取出来,形成一种通用范例
单例模式
单例模式(只需要一个对象产生,不需要反复产生多个对象)
<head>
<link rel="stylesheet" href="3.util.css">
</head>
<body>
<button onclick="test()">弹出遮罩层</button>
<script src="3.util.js"></script>
<script>
let myObj={};
//json数据就是依照单例模式的概念产生的数据模式
let obj={
name:"月月",
age:24,
method1:{
f1(){
return "f1";
},
f2(){
return "f2";
}
}
}
//弹出遮罩层案例
function test() {
/*let div=createDiv(); //返回的对象
div.show();*/
createDiv();
}
</script>
</body>
3.util.js文件
/*let createDiv=function () {
let div=document.createElement("div");
div.className="layer";
document.body.appendChild(div); // 放到页面显示出来
let show=function () {
div.style.display="block";
document.body.style.overflow="hidden"
}
return {
show,
}
//应该只create一次,不然每次点击都创建div,可能会造成反复叠加
}*/
// 正确写法
let createDiv=(function () {
let div;
return function () {
if(div==undefined){
div=document.createElement("div");
div.className="layer";
document.body.appendChild(div)
}
let show=function () {
div.style.display="block";
document.body.style.overflow="hidden"
}
show();
}
})()
3.util.css文件
body{
height: 1500px;
}
.layer{
position: absolute;
top:30px;
left:0;
width: 100%;
height: 100%;
background-color: black;
opacity: 0.3;
display: none;
}
效果
示例:
/*
野兽约美女,主动微信联系
1.需要两个对象,美女+野兽
2.需要通过微信
3.先看美女有没有微信,如果有微信就直接通过微信联系,如果没有就先安装微信
4.两个单例之间开始通信
*/
//野兽
let yeShou={
callMeiNv:function (msg) {
let Mn=meiNv.getMessage(msg);
alert(Mn.weChar)
}
}
//美女
let meiNv=(function () { //meiNv={}
let wxApp=function(message) { //微信构造函数
this.weChar=message
}
let weChar;
let info={ //美女信息
getMessage:function (message) {
console.log(message)
if(!weChar){ //没有微信
weChar=new wxApp(message)
}
return weChar; //对象,wxmini.wxmini
}
}
return info;
})()
yeShou.callMeiNv("一起吃饭吗?")
工厂模式
//类似于做架构(只需要调函数传参数)
function createPerson() {
function Person() {
//一定会得到人,但是是个什么样的人,不确定(弊端是不留接口的话Person()不能扩展)
}
let a=new Person();
return a;
}
// new Person(); 不可用,因为Person()在createPerson()中,改不到
createPerson();
function Plane() {
}
Plane.prototype.speed=30; //可随意更改模板
//原型模式
function student() {
}
student.prototype.name="月亮";
student.prototype.work=function () {
}
//构造函数
function myStudent(name) {
this.name=name;
this.work=function () {
}
}
console.log(new myStudent("月月")) //有constructor属性
/* 原型+构造(工作中使用)*/
function emp(name) {
this.name=name;
}
// emp.prototype.work=function () {
//
// } 有constructor属性
emp.prototype={
work(){},
study(){},
//解决没有constructor属性(自己加上去)
constructor:emp
}
console.log(new emp("月亮")) //没有constructor属性
class Demo{
constructor() {
//属性
}
//方法
}
状态模式
<button onclick="myMove('jump')">跳</button>
<button onclick="myMove('run')">跑</button>
<button onclick="myMove('walk')">走</button>
<script>
function myMove(a) {
obj[a]();
}
let obj={
jump(){
console.log("跳")
},
run:function () {
console.log("跑")
},
walk(){
console.log("走")
}
}
/*let obj={
method1(){
console.log("method1")
},
method2(){
console.log("method2")
},
method3(){
console.log("method3")
},
}
let a=1;
if(a==1){
obj.method1()
}else if(a==2){
obj.method2()
}else if (a==3){
obj.method3()
}
let a="method1";
obj[a]();*/
</script>
观察者模式
<div id="box">观察者模式</div>
<script>
document.getElementById("box").addEventListener("click", function () {
alert("hello 世界")
})
//vue---Object.defineProperty() 参考:js笔记中的数据双向绑定原理
/*
观察者模式,属于行为模式的一种,定义了一对多的依赖关系,让多个观察者同时监听一个主题对象,
这个主题对象在状态发生变化的时候,会通知所有的观察者,使他们自动更新。
和观察者模式很像的:发布订阅模式
*/
</script>
桥接模式
桥接方式:降低代码耦合度
<!--
<input type="button" value="300x300" id="inp1" οnclick="changeSize(this)">
<input type="button" value="500x500" id="inp2" οnclick="changeSize(this)">
<input type="button" value="700x700" id="inp3" οnclick="changeSize(this)">
-->
<input type="button" value="300x300" id="inp1">
<input type="button" value="500x500" id="inp2">
<input type="button" value="700x700" id="inp3">
<div>
<img src="duorou.jpg" alt="">
</div>
<script>
//普通方式:
/*function changeSize(obj) {
let btnValue=obj.value;
btnValue=btnValue.split("x")
console.log(btnValue)
let size={
width:btnValue[0],
height:btnValue[1]
}
let imgObj=document.getElementsByTagName("img")[0];
imgObj.style.width=size.width+"px";
imgObj.style.height=size.height+"px";
}*/
//桥接方式:降低代码耦合度
let changeSize=function (btnValue) {
let bValue=btnValue.split("x");
let size={
width:bValue[0],
height:bValue[1]
}
let imgObj=document.getElementsByTagName("img")[0];
imgObj.style.width=size.width+"px";
imgObj.style.height=size.height+"px";
}
// changeSize("100x100") 每一段都可以单独执行
//桥
let changeSizeBridge=function (e) {
let val=e.target;
console.log(val.value);
changeSize(val.value)
}
//绑定事件
function addEvent(eleObj,eName,eMethod) { //3个参数:元素对象,事件名称,方法
let obj=document.getElementById(eleObj); //找到页面的节点
if("click"==eName){
obj.onclick=function () {
eMethod(event)
}
}
}
addEvent("inp1","click",changeSizeBridge)
addEvent("inp2","click",changeSizeBridge)
addEvent("inp3","click",changeSizeBridge)
</script>