解读sencha touch移动框架的核心架构(一)

简介:

sencha的前身就是Extjs了,sencha 框架是世界上第一个基于HTML5的Mobile App框架

那么何谓框架,传统软件工程对于库和框架的区分主要着眼于对应用运行流程的控制权,框架提供架构,控制运行流程,让开发者在合适的地方书写针对具体问题的代码

sencha提倡的就是组件化编程,是面向对象的技术的一种近一步的发展延伸,类的概念仍然是组件技术中一个基础的概念,但是组件技术更核心的概念是接口。

sencha是重量级的架构了,一般来说很少会有公司用到内部的这种架构,因为太像java的Swing了

不过我在项目中用sencha组织的代码结构拿来主义本来不是我的风格,自己也改动了很多代码, 但是整体的设计还是参考的sencha了

有项目图为证:3万行以上的纯js代码架构哦~

AMD + sencha核心

AMD模块

sencha架构模块

AMD/CMD的实现只用了100行不到的代码,只是为简单的管理模块

在强类型语言中,继承机制是得到语言本身的支持的,就算代码开发者比较一般,也不会出太大的问题,但是js就不同了,要实现这一套机制就有一套很复杂的模拟

当然这里性能与维护扩展本来就是一个单选题 - -.

当然像backbone这种也是类似的提供纯架构方案

为什么我选择sencha作为参考架构呢?

高端大气上档次

关于Ext/sencha的好与坏这里就不多加讨论了,它的精华是需要你去慢慢体会的

 


按照最新sencha 2.3.1源码的区分

从Ext4.0开始,风格大变,提供一个完整的沙箱模式

就只针对core文件夹的内容,具体就是这么几个文件了,

Ext.js,Base.js,Class.js,ClassManager.js,Loader.js

这里是架构的核心文件,架构真心有点复杂,先看看历史的演变,老版本的架构

 


EXTJS组件化编程

组件化的简单定义:

组件化的基础是面向对象,在面向对象编程的基础上将一个或多个小部件封装到一起,成为一个模块,让其成为一个新的组件(适合我们需求的组件),每一个模块都应当具备单独运行的能力

image

通过继承来实现了对象的封装,ExtJS最底层的那个基类是Observable,它提供了最基础的事件机制,通过层层的封装与扩展,它的派生类中是越来越庞大,所提供的功能也越来越多,就比如Window这个组件,它继承自Panel并添加了默认的resizabel,closable,draggable等属性(Panel也可以加入类似的函数,但是需要编码实现)。而Panel又继承自Container,并加入了渲染Title和tbar等功能

 


先看老版本的实现继承的机制

Ext.extend( superclass, overrides )  在4.0后就作废了,统一换成了Ext.define的架构方式

先看3.4版本的,之后在过渡4.0,发现是一个多么大的跨越

复制代码
Ext.apply(Ext, {

        /**
         * This method deprecated. Use {@link Ext#define Ext.define} instead.
         * @method
         * @param {Function} superclass
         * @param {Object} overrides
         * @return {Function} The subclass constructor from the `overrides` parameter, or a generated one if not provided.
         * @deprecated 2.0.0 Please use {@link Ext#define Ext.define} instead
         */
        extend: function() {
            // inline overrides
            var objectConstructor = objectPrototype.constructor,
                inlineOverrides = function(o) {
                for (var m in o) {
                    if (!o.hasOwnProperty(m)) {
                        continue;
                    }
                    this[m] = o[m];
                }
            };

            return function(subclass, superclass, overrides) {
                // First we check if the user passed in just the superClass with overrides
                if (Ext.isObject(superclass)) {
                    overrides = superclass;
                    superclass = subclass;
                    subclass = overrides.constructor !== objectConstructor ? overrides.constructor : function() {
                        superclass.apply(this, arguments);
                    };
                }

                //<debug>
                if (!superclass) {
                    Ext.Error.raise({
                        sourceClass: 'Ext',
                        sourceMethod: 'extend',
                        msg: 'Attempting to extend from a class which has not been loaded on the page.'
                    });
                }
                //</debug>

                // We create a new temporary class
                var F = function() {},
                    subclassProto, superclassProto = superclass.prototype;

                F.prototype = superclassProto;
                subclassProto = subclass.prototype = new F();
                subclassProto.constructor = subclass;
                subclass.superclass = superclassProto;

                if (superclassProto.constructor === objectConstructor) {
                    superclassProto.constructor = superclass;
                }

                subclass.override = function(overrides) {
                    Ext.override(subclass, overrides);
                };

                subclassProto.override = inlineOverrides;
                subclassProto.proto = subclassProto;

                subclass.override(overrides);
                subclass.extend = function(o) {
                    return Ext.extend(subclass, o);
                };

                return subclass;
            };
        }(),

        /**
         * Proxy to {@link Ext.Base#override}. Please refer {@link Ext.Base#override} for further details.
         *
         * @param {Object} cls The class to override
         * @param {Object} overrides The properties to add to `origClass`. This should be specified as an object literal
         * containing one or more properties.
         * @method override
         * @deprecated 2.0.0 Please use {@link Ext#define Ext.define} instead.
         */
        override: function(cls, overrides) {
            if (cls.$isClass) {
                return cls.override(overrides);
            }
            else {
                Ext.apply(cls.prototype, overrides);
            }
        }
    });
复制代码

在4.0以前的架构还是相对比较简单的,只是用了一个关键的继承,不像4.0以后那就是一套完整的沙箱架构

针对JS的继承机制,那本红本书高3已经把细节讲的很透彻了

当然也有漏掉的,比如创建一个空函数的作用

var F = function() {},
     F.prototype = superclassProto;
     subclassProto = subclass.prototype = new F();

backbone的继承机制基本大同小异

 


实现详解

一般继承的手段无非就是两种,原型继承与对象冒充

⒈原型继承就是利用了原型的查找合函数的作用域,好处就是内存处只有一份,坏处就是原型是共享的,如果有引用类型所有的实例都可以被修改

⒉对象冒充就是拷贝属性了,把所有的实例属性与方法都拷贝一次,坏处自然就是每一份拷贝都是占独立的一份空间了

原型继承自然就是引用原型链了,这个prototype没什么好说的,但是不能继承静态属性,因为这个不在原型链上

对象冒充,就是通过call,apply处理的,因为JS有运行作用域的,要注意了prototype上的的属性是不会被处理的

现在看看Ext的完美解决方案

看下面例子,实现一个最基本的继承

复制代码
var a = function(id){
    this.name = id;
}

a.prototype = {
    sayA : function(){
        alert(this.name)
    }
};

var b = Ext.extend(a, {
    constructor:function(name){
        this.name = name;
    },
    sayB : function(){
        this.constructor.superclass.constructor(111)
    }
});

c =  new b('Aaron')
复制代码

ext需要解决的问题

1 构造器问题:类b没有构造器,直接是通过Ext.extend生成的,所以内部可定需要类似工厂方法,生成一个类的包装器

2 父类调用:原型只能继承原型链上的属性与方法,如果要调用父类构造器,如何处理?所以ext需要留一个接口出来可以调用父类

3 静态方法处理

4 实现继承后,构造器引用被修改

 

本文转自艾伦 Aaron博客园博客,原文链接:http://www.cnblogs.com/aaronjs/p/3578495.html,如需转载请自行联系原作者

相关文章
|
12天前
|
机器学习/深度学习
ACM MM24:复旦提出首个基于扩散模型的视频非限制性对抗攻击框架,主流CNN和ViT架构都防不住它
【9月更文挑战第23天】复旦大学研究团队提出了ReToMe-VA,一种基于扩散模型的视频非限制性对抗攻击框架,通过时间步长对抗性潜在优化(TALO)与递归令牌合并(ReToMe)策略,实现了高转移性且难以察觉的对抗性视频生成。TALO优化去噪步骤扰动,提升空间难以察觉性及计算效率;ReToMe则确保时间一致性,增强帧间交互。实验表明,ReToMe-VA在攻击转移性上超越现有方法,但面临计算成本高、实时应用受限及隐私安全等挑战。[论文链接](http://arxiv.org/abs/2408.05479)
25 3
|
15天前
|
Kubernetes Java Android开发
用 Quarkus 框架优化 Java 微服务架构的设计与实现
Quarkus 是专为 GraalVM 和 OpenJDK HotSpot 设计的 Kubernetes Native Java 框架,提供快速启动、低内存占用及高效开发体验,显著优化了 Java 在微服务架构中的表现。它采用提前编译和懒加载技术实现毫秒级启动,通过优化类加载机制降低内存消耗,并支持多种技术和框架集成,如 Kubernetes、Docker 及 Eclipse MicroProfile,助力开发者轻松构建强大微服务应用。例如,在电商场景中,可利用 Quarkus 快速搭建商品管理和订单管理等微服务,提升系统响应速度与稳定性。
31 5
|
29天前
|
存储 Java Maven
从零到微服务专家:用Micronaut框架轻松构建未来架构
【9月更文挑战第5天】在现代软件开发中,微服务架构因提升应用的可伸缩性和灵活性而广受欢迎。Micronaut 是一个轻量级的 Java 框架,适合构建微服务。本文介绍如何从零开始使用 Micronaut 搭建微服务架构,包括设置开发环境、创建 Maven 项目并添加 Micronaut 依赖,编写主类启动应用,以及添加控制器处理 HTTP 请求。通过示例代码展示如何实现简单的 “Hello, World!” 功能,并介绍如何通过添加更多依赖来扩展应用功能,如数据访问、验证和安全性等。Micronaut 的强大和灵活性使你能够快速构建复杂的微服务系统。
61 5
|
29天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
58 2
|
1月前
|
设计模式 开发框架 前端开发
在开发框架中实现事件驱动架构
【9月更文挑战第2天】事件驱动架构(EDA)通过事件机制让组件间解耦交互,适用于动态扩展和高响应性的系统。本文提供一个基于Beego框架实现事件驱动的示例,通过事件管理器注册和触发事件,实现用户注册和登录时的不同处理逻辑,展示了其在Web应用中的灵活性和高效性。
64 5
|
2月前
|
XML 开发框架 .NET
.NET框架:软件开发领域的瑞士军刀,如何让初学者变身代码艺术家——从基础架构到独特优势,一篇不可错过的深度解读。
【8月更文挑战第28天】.NET框架是由微软推出的统一开发平台,支持多种编程语言,简化应用程序的开发与部署。其核心组件包括公共语言运行库(CLR)和类库(FCL)。CLR负责内存管理、线程管理和异常处理等任务,确保代码稳定运行;FCL则提供了丰富的类和接口,涵盖网络、数据访问、安全性等多个领域,提高开发效率。此外,.NET框架还支持跨语言互操作,允许开发者使用C#、VB.NET等语言编写代码并无缝集成。这一框架凭借其强大的功能和广泛的社区支持,已成为软件开发领域的重要工具,适合初学者深入学习以奠定职业生涯基础。
90 1
|
2月前
|
消息中间件 Kafka Java
Spring 框架与 Kafka 联姻,竟引发软件世界的革命风暴!事件驱动架构震撼登场!
【8月更文挑战第31天】《Spring 框架与 Kafka 集成:实现事件驱动架构》介绍如何利用 Spring 框架的强大功能与 Kafka 分布式流平台结合,构建灵活且可扩展的事件驱动系统。通过添加 Spring Kafka 依赖并配置 Kafka 连接信息,可以轻松实现消息的生产和消费。文中详细展示了如何设置 `KafkaTemplate`、`ProducerFactory` 和 `ConsumerFactory`,并通过示例代码说明了生产者发送消息及消费者接收消息的具体实现。这一组合为构建高效可靠的分布式应用程序提供了有力支持。
85 0
|
10天前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
10天前
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
2月前
|
Kubernetes Cloud Native Docker
云原生之旅:从容器到微服务的架构演变
【8月更文挑战第29天】在数字化时代的浪潮下,云原生技术以其灵活性、可扩展性和弹性管理成为企业数字化转型的关键。本文将通过浅显易懂的语言和生动的比喻,带领读者了解云原生的基本概念,探索容器化技术的奥秘,并深入微服务架构的世界。我们将一起见证代码如何转化为现实中的服务,实现快速迭代和高效部署。无论你是初学者还是有经验的开发者,这篇文章都会为你打开一扇通往云原生世界的大门。
下一篇
无影云桌面