当前位置: 首页 > wzjs >正文

制作网站题材如何判断网站是不是自适应

制作网站题材,如何判断网站是不是自适应,seo优化前景,网站可以做多少优化关键词MVP(Model-View-Presenter)是一种软件架构模式。 MVP模式组成 Model 职责:负责数据管理和业务逻辑包含:数据存储、数据获取、业务规则、数据验证等特点:独立于用户界面,可以被多个View复用 View 职责&#…

MVP(Model-View-Presenter)是一种软件架构模式。

MVP模式组成

Model

  • 职责:负责数据管理和业务逻辑
  • 包含:数据存储、数据获取、业务规则、数据验证等
  • 特点:独立于用户界面,可以被多个View复用

View

  • 职责:负责用户界面的显示和用户交互
  • 包含:UI组件、用户输入处理、界面渲染等
  • 特点:被动的,不直接与Model交互,只与Presenter通信

Presenter

  • 职责:作为Model和View之间的中介
  • 包含:处理用户交互逻辑、格式化数据、控制View更新等
  • 特点:包含表示层逻辑,协调Model和View的交互

MVP模式数据流向

在这里插入图片描述

在这里插入图片描述

代码

用MVP模式实现CounterApp
model层
model应该有让调用方订阅和通知订阅方的能力。

export interface IModel<ModelData, ModelEvent> {addEventListener<T extends keyof ModelEvent>(type: T, callback: ModelEvent[T]): DisposeHandler;subscribeModelData(callback: (data: ModelData) => void): DisposeHandler;getModelData(): ModelData;
}

CounterModel的类型定义

export type CounterModelEvent = {"data:update": (data: number) => void;
};export type CounterModelData = numberexport interface ICounterModel extends IModel<CounterModelData, CounterModelEvent> {count : number
}

定义ICounterModel,面相接口编程。
CounterModel的代码实现

export class CounterModel implements ICounterModel
{eventemitter = new EventEmitter<CounterModelEvent>();private _count: number = 0;getModelData() {return this.count;}protected notifyDataUpdate(): void {this.eventemitter.emit("data:update", this.getModelData());}addEventListener<T extends keyof CounterModelEvent>(type: T,callback: CounterModelEvent[T]): DisposeHandler {this.eventemitter.on(type, callback as any);return () => {this.eventemitter.off(type, callback);};}subscribeModelData(callback: (data: CounterModelData) => void): DisposeHandler {return this.addEventListener("data:update", callback);}get count() {return this._count;}set count(value: number) {this._count = value;this.notifyDataUpdate();}
}

view层
view应该有订阅业务事件和渲染视图的能力

export interface IView<ViewEvent extends Record<string, Function>, ViewRenderData extends Object> {addEventListener<T extends keyof ViewEvent>(type: T, callback: ViewEvent[T]): () => void;render(data: ViewRenderData): void;destroy(): void;}

ICounterView类型定义

export type CounterViewEvent = {"click:increment": () => void;"click:decrement": () => void;
};export type CounterViewRenderData = {count: number;
};export interface ICounterView extends IView<CounterViewEvent, CounterViewRenderData> {}

CounterView代码

class CounterView implements ICounterView {private disposeList: DisposeHandler[] = [];private container: HTMLElement;private counterContainer!: HTMLDivElement;private eventemitter = new EventEmitter<CounterViewEvent>();constructor(container: HTMLElement) {this.container = container;this.init();}// 初始化视图绑定视图事件init() {this.disposeList.push(this.createDecrementButton());this.createCounterContainer()this.disposeList.push(this.createIncrementButton());}private createIncrementButton() {const incrementButton = document.createElement("button");incrementButton.textContent = "Increment";const handler = () => {this.eventemitter.emit("click:increment");};incrementButton.addEventListener("click",handler );return () => {incrementButton.removeEventListener("click", handler);};}private createCounterContainer() {const counterContainer = document.createElement("div");counterContainer.textContent = "0";this.container.appendChild(counterContainer);}private createDecrementButton() {const decrementButton = document.createElement("button");decrementButton.textContent = "Decrement";const handler = () => {this.eventemitter.emit("click:decrement");};decrementButton.addEventListener("click", handler);return () => {decrementButton.removeEventListener("click", handler);};}addEventListener<T extends keyof CounterViewEvent>(type: T,callback: CounterViewEvent[T]): () => void {this.eventemitter.on(type, callback);return () => {this.eventemitter.off(type, callback);};}render(data: { count: number }) {this.counterContainer.textContent = data.count.toString();}destroy(): void {this.disposeList.forEach((dispose) => dispose());this.container.innerHTML = "";}
}

Presenter
CounterPresenter负责协调counterModel和counterView。

export class CounterPresenter implements IPresenter {private counterModel: ICounterModel;private counterView: ICounterView;constructor(counterModel: CounterModel, counterView: ICounterView) {this.counterModel = counterModel;this.counterView = counterView;}init() {this.bindViewEvent();this.bindModelEvent();}bindViewEvent() {this.counterView.addEventListener("click:increment", () => {this.counterModel.count += 1;});this.counterView.addEventListener("click:decrement", () => {this.counterModel.count -= 1;});}bindModelEvent() {this.counterModel.addEventListener("data:update", (data) => {this.counterView.render({ count: data });});}destroy(): void {this.counterModel = null;this.counterView = null;}
}

CounterApp负责初始化Model,View和Presenter,管理应用的生命周期,对外提供接口。

export class CounterApp {private counterModel!: CounterModel;private container: HTMLElement;private counterView!: CounterView;private counterPresenter!: CounterPresenter;constructor(container: HTMLElement) {this.container = container;this.createModels();this.createViews();this.createPresenters();this.initPresenters();}private createModels() {this.counterModel = new CounterModel(sameDetector);}private createViews() {this.counterView = new CounterView(this.container);}private createPresenters() {this.counterPresenter = new CounterPresenter(this.counterModel, this.counterView);}private initPresenters() {this.counterPresenter.init();}destroy() {this.counterPresenter.destroy();this.counterView.destroy();this.counterModel = null;}
}

用react的同学都知道,react有批处理机制,这里对model也做一个简单优化,避免一段逻辑触发多次model数据更新通知。
model接口修改添加两个方法

export interface IModel<ModelData, ModelEvent> {// ......startBatchUpdate(): void; // 开始批量更新finishBatchUpdate(): void; // 结束批量更新
}

数据层批处理的代码是类似的,行为可以让子类重写
BaseModel定义批处理流程


export abstract class BaseModel<ModelData, ModelEvent> implements IModel<ModelData, ModelEvent> {protected _isStartBatchUpdate: boolean = false; // 是否开始批量更新private beforeStartBatchUpdateModelData: ModelData | null = null; // 批量更新前的模型数据startBatchUpdate() {this._isStartBatchUpdate = true; // 开始批量更新this.beforeStartBatchUpdateModelData = this.getModelData(); // 记录批量更新前的模型数据}abstract getModelData(): ModelData;abstract isSame(oldData: ModelData, newData: ModelData): boolean;abstract addEventListener<T extends keyof ModelEvent>(type: T, callback: ModelEvent[T]): () => void;abstract subscribeModelData(callback: (data: ModelData) => void): () => void;finishBatchUpdate() {this._isStartBatchUpdate = false; // 结束批量更新if (this.beforeStartBatchUpdateModelData) {// 如果有批量更新前的模型数据,则比较是否有变化if (this.isSame(this.beforeStartBatchUpdateModelData, this.getModelData())) {return; // 如果没有变化,则不通知数据更新}this.beforeStartBatchUpdateModelData = null; // 清空批量更新前的模型数据}this.notifyDataUpdate(); // 通知数据更新}protected abstract notifyDataUpdate(): void; // 通知数据更新
}

这个例子view,model,presenter复杂度低,没有涉及多个view,model和presenter的情况,虽然比较简单,能通过这个应用理解MVP模式。

模式特点model层和view层解耦,presenter负责协调view层和model层。
优点

  • 依赖接口可以方便进行mock测试
  • model层独立于view层,可以被多个view层使用
  • 数据流向清晰

缺点

  • 简单应用容易复杂化
  • 事件驱动容易提高调试复杂度,观察者模式也容易提高调试复杂度
  • Presenter层承担太多职责容易导致臃肿
  • 团队开发成本比较高
http://www.dtcms.com/wzjs/785327.html

相关文章:

  • 网站编辑是做网页编辑吗wordpress301重定向
  • vps 需刷新几次才能打开网站wordpress!资源
  • 快速做网站套餐wordpress链接跳转错误
  • 在一起做网店的网站的怎么购买越影网站建设
  • 衡粘水佩网站建设手机搭建网站工具
  • 物流网站 源码在线短网址生成工具
  • 网页设计模板html代码字体大小seo排名赚能赚钱吗
  • 单产品网站建设上海装修公司电话
  • 站长之家源码重庆建设工程管理网
  • 网站开发移动端多少钱平潭建设局网站
  • 网站到底备案好不好国外设交网站开发客户的重要性
  • 个人网站空间申请广州微网站建设咨询
  • 手机购物网站怎么推广wordpress4.x
  • 做网站用什么好建设网站网络公司
  • 网站建设会遇到哪些难题淘宝联盟的网站怎么做
  • 大型网站为什么难做wordpress 开发 主题授权
  • php商城建站系统公司网站进不去qq空间
  • 朋友让帮忙做网站旅游网站建设风险分析
  • 昆山做网站的公司虞城做网站
  • 网站ftp地址是什么dw做网站背景图片设置
  • django做网站和js做网站广告设计公司名称
  • 安徽网站推广优化做网站用的各种图标大全
  • 怎么建设vip电影网站有限责任公司和有限公司有啥区别
  • moodle网站建设门户网站建设技术要求
  • ie的常用网站建设机械网站
  • 泉州自主建站模板厂房装修多少钱一个平方米
  • 红色ppt模板免费下载网站上海徐家汇网站建设
  • 呼和浩特市网站电商网站建设课设
  • 电商网站建设在哪里找设计师足球比赛直播中国队
  • 如何对网站做渗透淘宝上新推荐