框架设计-数显分离

设计模式 专栏收录该内容
26 篇文章 1 订阅

概述

无论是前端业务,还是各种游戏系统和玩法,随着时间的推移,都会变得越来越复杂,越来越庞大,越来越繁琐,解决复杂业务的一个解决方案就是数据驱动(Data Driven)。数据驱动的核心思想是——数显分离,以数据为中心,业务只是数据的各种不同呈现形式。无论逻辑多么繁杂,纯粹的数据都只有一份,而且非常简单。下面看看如何逐步的实现,数显分离…

示例

为了方便说明,假设有一个显示对象 Display,它有一个坐标属性 x,y,如下:

class Display {
    let x;
    let y;
}

现在有一个很简单的逻辑,修改显示对象的坐标,最常规的写法如下:

// 常规面向对象写法
class Controller {
    Display display;
    function setLogic(x, y) {
        this.display.x = x;
        this.display.y = y;
    }
}

常规的写法,就是根据传入参数修改,直接对象的属性值。

分离数据和显示

为了实现数显分离,逐步对上述代码,进行迭代。

第一步,抽离数据,然后根据数据刷新显示对象。

// 数显分离写法
class Data {
	let x;
	let y;
}

class Controller {
    Data data;
    Display display;

    function setData(data) {
        this.data = data;
        this.updateDisplay();
    }
    function updateDisplay() {
        this.display.x = this.data.x;
        this.display.y = this.data.y;
    }
}

抽离数据之后,有了数据和显示对象两个明确的概念。Controller 中要做的是,当外界数据变化时,通知后 Controller,Controller 会根据数据刷新显示显示。

实体

若是在刷新 display 位置之前,还有很多相关的逻辑,这些逻辑就会充斥着整个 Controller。
特别是当数据和显示对象都有很多个时,Controller 就会变得异常复杂和臃肿,如:

// 数显分离写法
class Controller {
    Data data;
    Display display;
    Data data1;
    Display display1;
    // ... 更新显示对象和数据

    function setData(data) {
        this.data = data;
        this.otherLogic();
        this.updateDisplay();
    }
    function otherLogic() {
    }
    function setData1(data) {
        this.data1 = data;
        this.otherLogic1();
        this.updateDisplay1();
    }
    function otherLogic1() {
    }
    function updateDisplay() {
        this.display.x = this.data.x;
        this.display.y = this.data.y;
        this.display1.x = this.data1.x;
        this.display1.y = this.data1.y;
    }
}

为了解决这一问题,再封装一个实体对象,来处理显示对象的相关逻辑。

// 基于实体数显分离写法
class Entity {
    let x;
    let y;
    Display display;
    function otherLogic() {
    }
    function updateDisplay() {
        this.display.x = this.x;
        this.display.y = this.y;
    }
}

class Controller {
    Data data;
    Entity entity;
    Data data1;
    Entity entity1;

    function setData(data) {
        this.data = data;
        this.entity.otherLogic();
        this.updateDisplay();
    }
    function setData1(data1) {
        this.data1 = data;
        this.entity1.otherLogic();
        this.updateDisplay();
    }
    function updateDisplay() {
        this.entity.x = this.data.x;
        this.entity.y = this.data.y;
        this.entity1.x = this.data1.x;
        this.entity1.y = this.data1.y;
    }
}

新增实体类的责任是处理实体相关的逻辑。

实体数据

将显示对象的逻辑抽离之后, Contoller 的逻辑变得非常简单的,就是根据数据去刷新实体。
但 Contoller 中还存在着大量数据及其赋值的重复代码,因此将数据也封装到实体对象中。

// 基于包含数据实体的数显分离写法
class Entity {
    Data data;
    Display display;
    function setData(data) {
        this.data = data;
        this.otherLogic();
        this.updateDisplay();
    }
    function otherLogic() {
    }
    function updateDisplay() 
    {
        this.display.x = this.data.x;
        this.display.y = this.data.y;
    }
}
class Controller {
    Entity entity;
    Entity entity1;
    function setData(data) {
        this.entity.setData(data);
    }
    function setData1(data) {
        this.entity1.setData(data);
    }
    function updateDisplay() {
        this.entity.updateDisplay()
        this.entity1.updateDisplay()
    }
}

将数据移入到实体中,实体负责处理它自己的逻辑和显示的更新,简化了 Controller。

缺点也要明确,实体现在关联了对应的数据对象,增加了耦合

实体接口

这样封装后 Controller 的变得简了洁很多,但是却带了另一个问题,层次深了之后,获取数据需要写大量重复代码,比如现在要获取显示的对象的坐标值。
代码就变成了这样:

// 基于包含数据实体的数显分离写法
class Entity {
    Data data;
    Display display;
    function setData(data) {
        this.data = data;
        this.otherLogic();
        this.updateDisplay();
    }
    function otherLogic() {
    }
    function updateDisplay() 
    {
        this.display.x = this.data.x;
        this.display.y = this.data.y;
    }
    function getX() {
        return this.display.x;
    }
    function getY() {
        return this.display.y;
    }
}
class Controller {
    Entity entity;
    Entity entity1;
    function setData(data) {
        this.entity.setData(data);
    }
    function setData1(data) {
        this.entity1.setData(data);
    }
    function updateDisplay() {
        this.entity.updateDisplay()
        this.entity1.updateDisplay()
    }
    function getEntityX() {
        return this.entity.getX();
    }
    function getEntityY() {
        return this.entity.getY();
    }
    function getEntity1X() {
        return this.entity1.getX();
    }
    function getEntity1Y() {
        return this.entity1.getY();
    }
}

若是外界需要获取更多实体的数据,Contoller 中就会不断的增加这样的方法。怎么解决呢?可以使用接口。
首先要明确,实体是系统内部的实现,是不对外公开的。可以增加一些接口,提供给外界使用。

// 基于包含数据实现接口实体的数显分离写法
interface IEntity {
    getX()
    getY()
}
class Entity {
    Data data;
    Display display;
    function setData(data) {
        this.data = data;
        this.otherLogic();
        this.updateDisplay();
    }
    function otherLogic() {
    }
    function updateDisplay() 
    {
        this.display.x = this.data.x;
        this.display.y = this.data.y;
    }
    function getX() {
        return this.display.x;
    }
    function getY() {
        return this.display.y;
    }
}
class Controller {
    Entity entity;
    Entity entity1;
    function setData(data) {
        this.entity.setData(data);
    }
    function setData1(data) {
        this.entity1.setData(data);
    }
    function updateDisplay() {
        this.entity.updateDisplay()
        this.entity1.updateDisplay()
    }
    function getEntity() {
        return this.entity as IEntity;
    }
    function getEntity1() {
        return this.entity1 as IEntity;
    }
}

加上接口之后,外面需要更多的数据时,首先在接口中添加方法,然后在实体各自实现接口中的方法即可,而无需修改 Controller 的内容。使用时,直接获取 IEntity 接口对象,通过该对象调用接口中的方法。

这样面向接口的方式,适合软件各个模块的直接的交互。

  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
引言: 在很多数字化与自动化设备中,执行器件的位移是作为关键的目标来进行控制的,这其中,包括角度(角位移)、直线位移与其他形式的位置移动等。在诸多位移检测器件中,光电编码器是较为常见的一种。其中的旋转编码器通常直接用于检测角度变化,而线性编码器,通常是光栅尺,则用于检测直线移动部件的位移变化。 对于输出信号为差分信号的光栅尺,经过长线接口处理后的信号同样。 如图所示 HCTL-2032光栅数显设计概述: HCTL-2032是Avago公司生产的一种可用于正交编码器鉴相与倍频计数的集成电路。该芯片内置两个正交编码器接口,内置前向滤波、鉴相、倍频与计数电路,可方便地为不具备正交解码功能的微控制器提供编码器接口功能。本文以STC89C52与HCTL-2032为主要器件,设计了一种可同时显示两路光栅计数值的数显表,并实现了其基本功能。 该设计结构图如下: HCTL-2032功能分析: 可以将光电编码器输出的波形转换成数字信号输入微处理器,两路输入引脚CHAx、CHAy、CHIx和CHBx、CHBy、CHIy经过施密特触发器整形滤波后,通过设置EN1、EN2的值选择采用4×、2×、1×计数模式,而后送入32 位二进制计数器对采集的正交波计数,由于输出数据线只有8位,因此32位的数据需要通过改变控制线SEL1、SEL2、OE的值分四次依次读出。 附件内容包括: 基于HCTL-2032光栅数显表电路设计(STC89C52与HCTL-2032接口电路),用AD软件打开; 源程序,包括初始化单片机与HCTL-2032和读取HCTL-2032的计数值; 该光栅数显设计论文分析word文档以及参考设计文档;
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值