前端代码的三种设计模式

为了便于理解,以下代码示例采用的都是 React + rdeco 编写,设计模式本身是高度抽象的,并不局限于某一类特定的框架

成都创新互联公司专注为客户提供全方位的互联网综合服务,包含不限于做网站、成都网站制作、高碑店网络推广、小程序设计、高碑店网络营销、高碑店企业策划、高碑店品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;成都创新互联公司为所有大学生创业者提供高碑店建站搭建服务,24小时服务热线:13518219792,官方网址:www.cdcxhl.com

组件模式

组件模式是我们用的最多的或者说目前大家都唯一能够理解的模式,组件模式的特点是,予以每个组件独立的上下文,组件和组件之间有严格的代码隔离,通常在不考虑全局变量的影响下组件之间是完全无潜在交互的。

const Table = createComponent({
name:'table',
state:{
data:[],
},
view:{
render(){
return(
{this.state.data.map(d=>{
return d
})}

)
}
}
})
const Page = createComponent({
name:'page',
view:{
render(){
return(

)
}
}
})
复制代码

这种模式我们都很熟悉,Page 和 Table 是两个拥有独立上下文的组件,在不同的 UI 框架里有不同的组件交互方式,在 React 中,Page 如果要和 Table 进行交互,可以使用 props 传递,或者借助 Context 来共享一部分上下文。

但是这种模式在很多场景下并不是完全有效的,只有当我们非常明确两个组件之间的边界时,模式和实际情况才是相符合的,例如考虑这样一种场景:

const HeadTitle = ({text})=>{
return(

{text}


)
}
const Page = createComponent({
name:'page',
state:{
text:'page',
},
view:{
render(){

}
}
})
复制代码

在这个示例中,乍看是没啥问题,平时我们都会将一些无状态的 UI 提取为无状态的函数组件,但经过实践你会发现实际上,HeadTitle 大概率仅服务于 Page,也就是说 HeadTitle 并不是为了复用而被提取,更多是因为大型组件的文件需要拆解从而减小体积,降低管理难度。

但是以此为目的进行组件化拆解会破坏原有组件的完整性,导致大量的参数传递,这和我们过度提取代码到函数其实是一个效果。

function print(name){
console.log(name)
}
function main(){
const name = 'main'
print(name)
}
// 如果 print 在 main 函数内部则不需要再次传递 name
function main(){
const name = 'main'
function print(){
console.log(name)
}
print(name)
}
// 因此对于 main 来说 print 是一个独立函数?,还是一个代码片段?
复制代码

为了解决组件提取导致的上下文隔离问题,我们实践了一种模式,我们称之为组合模式。

组合模式

和组件模式相比,组合模式是一种轻量化的方案,相比组件模式两者有明显的区别。

  1. 组件模式拥有独立的上下文,组件和组件之间组合成新的组件需要进行上下文的传递,而组合模式则只是组件的一个片段,若干个组合体组成了一个完整组件,组合体之间共享上下文,不需要额外传递,但组合体本身实现了相关逻辑的内聚。
  2. 组件之间因为上下文隔离,因此可以拥有相同的内部成员,组合体只是组件的一个片段,组合体之间不能用相同的内部成员。
  3. 有实例,需要命名标识,组合体没有实例,不需要命名标识。

参照以上区别我们来看看的代码示例:

const table = createCompose({
view:{
renderTable(){
return(
{this.state.data.map(d=>{
return d
})}

)
}
}
})
const head = createCompose({
state:{
text:'page'
},
view:{
renderHead(){
return(

{text}


)
}
}
})
const Page = createComponent(compose({
name:'page',
state:{
data:[]
},
view:{
render(){
<>
{this.view.renderHead()}
{this.view.renderTable()}

}
}
},[table, head]))
复制代码

现在 head 和 table 都成了组合体,通过组合变成了 page 的一部分,为此他们可以共享彼此的上下文,而不用额外通过 props 或者 Context 来传递或者共享参数。

除了组合模式,我们还总结了第三种模式,membrane 模式,这种模式我在早期的文章中有提到过,今天我们将其简化。

Membrane 模式

和组合模式相比,membrane 模式具有一些共通性,例如同样没有独立的上下文,不需要命名标识,不过两者也有极大的区别。

  1. membrane 是一种抽象模式,和组合模式相比,每个 membrane 只能有一个模板。
  2. compose 和 membrane 可以联合使用。
const pageTemplate = () => {
return {
state:{
name:'',
},
service:{
init(){}
},
controller:{
onMount(){
this.service.init()
}
},
view:{
render(){
return(
{this.state.name}

)
}
}
}
}
const Page1Membrane = createMembrane(pageTemplate(), {
name:'page-1-membrane',
service:{
init(){
this.setter.name('page-1-membrane')
}
}
})
const Page1Membrane = createMembrane(pageTemplate(), {
name:'page-1-membrane',
service:{
init(){
this.setter.name('page-2-membrane')
}
}
})
const Page1 = createComponent(Page1Membrane)
// render Page1 name === page-1-membrane
const Page2 = createComponent(Page2Membrane)
// render Page2 name === page-2-membrane
复制代码

如果你熟悉面向对象设计,那么可能会很快联想到 membrane 和 抽象类的特性有些相似,不过相比抽象类,membrane 可以包含具体的实现,因此两者也不完全等价,但是从设计上是有一定的共通性的

在实际实践中,我们结合上述三种模式,借助类似 mermaid 这样的 UML 图形库,在日常迭代中增加了前端设计相关的内容,从实际结果看我们认为这些模式有助于改善前端设计的粗糙和非专业性,同时可以改善前端代码的标准化程度,利用 UML 图更好的代替注释和文字文档来描述业务代码的组成关系。

网页标题:前端代码的三种设计模式
标题来源:http://www.gawzjz.com/qtweb/news45/186545.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联