程序开发_程序开发心理学 - CSDN
精华内容
参与话题
  • 软件开发基本流程【一】

    万次阅读 多人点赞 2019-02-14 10:45:49
    它是一个对用户的需求进行去粗取精、去伪存真、正确理解,然后把它用软件工程开发语言(形式功能规约,即需求规格说明书)表达出来的过程。本阶段的基本任务是和用户一起确定要解决的问题,建立软件的逻辑模型,编写...

    分析 


    软件需求分析就是回答做什么的问题。它是一个对用户的需求进行去粗取精、去伪存真、正确理解,然后把它用软件工程开发语言(形式功能规约,即需求规格说明书)表达出来的过程。本阶段的基本任务是和用户一起确定要解决的问题,建立软件的逻辑模型,编写需求规格说明书文档并最终得到用户的认可。需求分析的主要方法有结构化分析方法、数据流程图和数据字典等方法。本阶段的工作是根据需求说明书的要求 ,设计建立相应的软件系统的体系结构,并将整个系统分解成若干个子系统或模块,定义子系统或模块间的接口关系,对各子系统进行具体设计定义,编写软件概要设计和详细设计说明书,数据库或数据结构设计说明书,组装测试计划 。


    设计 


    软件设计可以分为概要设计和详细设计两个阶段。实际上软件设计的主要任务就是将软件分解成模块是指能实现某个功能的数据和程序说明、可执行程序的程序单元。可以是一个函数、过程、子程序、一段带有程序说明的独立的程序和数据,也可以是可组合、可分解和可更换的功能单元。模块,然后进行模块设计。概要设计就是结构设计,其主要目标就是给出软件的模块结构,用软件结构图表示。详细设计的首要任务就是设计模块的程序流程、算法和数据结构,次要任务就是设计数据库,常用方法还是结构化程序设计方法。 


    编码 


    软件编码是指把软件设计转换成计算机可以接受的程序,即写成以某一程序设计语言表示的"源程序清单"。充分了解软件开发语言、工具的特性和编程风格,有助于开发工具的选择以及保证软件产品的开发质量。 
    当前软件开发中除在专用场合,已经很少使用二十世纪80年代的高级语言了,取而代之的是面向对象的开发语言。而且面向对象的开发语言和开发环境大都合为一体,大大提高了开发的速度。 


    测试 


    软件测试的目的是以较小的代价发现尽可能多的错误。要实现这个目标的关键在于设计一套出色的测试用例(测试数据和预期的输出结果组成了测试用例)。如何才能设计出一套出色的测试用例,关键在于理解测试方法。不同的测试方法有不同的测试用例设计方法。两种常用的测试方法是白盒法测试对象是源程序,依据的是程序内部的的逻辑结构来发现软件的编程错误、结构错误和数据错误。结构错误包括逻辑、数据流、初始化等错误。用例设计的关键是以较少的用例覆盖尽可能多的内部程序逻辑结果。白盒法和黑盒法依据的是软件的功能或软件行为描述,发现软件的接口、功能和结构错误。其中接口错误包括内部/外部接口、资源管理、集成化以及系统错误。黑盒法用例设计的关键同样也是以较少的用例覆盖模块输出和输入接口。黑盒法。 


    维护 


    维护是指在已完成对软件的研制(分析、设计、编码和测试)工作并交付使用以后,对软件产品所进行的一些软件工程的活动。即根据软件运行的情况,对软件进行适当修改,以适应新的要求,以及纠正运行中发现的错误。编写软件问题报告、软件修改报告 。 
    一个中等规模的软件,如果研制阶段需要一年至二年的时间,在它投入使用以后,其运行或工作时间可能持续五年至十年。那么它的维护阶段也是运行的这五年至十年期间。在这段时间,人们几乎需要着手解决研制阶段所遇到的各种问题,同时还要解决某些维护工作本身特有的问题。做好软件维护工作,不仅能排除障碍,使软件能正常工作,而且还可以使它扩展功能,提高性能,为用户带来明显的经济效益。然而遗憾的是,对软件维护工作的重视往往远不如对软件研制工作的重视。而事实上,和软件研制工作相比,软件维护的工作量和成本都要大得多。


    在实际开发过程中,软件开发并不是从第一步进行到最后一步,而是在任何阶段,在进入下一阶段前一般都有一步或几步的回溯。在测试过程中的问题可能要求修改设计,用户可能会提出一些需要来修改需求说明书等。

     

    1、项目设计 


    项目设计的主导思想,我觉得可以理解为两种,一种是完全设计,一个是简单设计。 
    完全设计是指在具体编写代码之前对软件的各种方面都调查好,做好详细的需求分析、编写好全部的开发文档,设计出程序全部流程后再开始写代码。 换句话说,就是全部的计划好了,能看到最终的样子,再开战。这好像也是很多“软件工程”书里要求的那样。开始的时候,我觉得这种方法不错也。什么都计划好了,照着做就是了。不过这里有个明显的问题,就是谁来做这个完美的计划?估计只有及其BT的人了,但是大部分人的想要完全设计,并且没有错误,或者已经有几种后备的容错方案,并能准确无误的推行。以达到最终目标。这样的境界,没有很多年的工作经历是不可能的。我也没有这样的本事,所以我也就放弃了这种想法。 
    简单设计:简单设计一种概念,一种可以接受的简单的设计,最起码数据库已经定下来,基本流程已经确定的方案,来作为程序设计的开始,并随时根据实际情况的进展来修正具体的功能设计,但这种功能修改不能是修改数据库结构。也就是说数据库结构是在编程之前经过反复论证的。这种方法减少了前期设计的时间,把代码编写工作和部分设计工作放在了一起,实际缩短了项目开发的时间。如果说完全设计方法要求有很厉害的前期设计人员,那么简单设计要求有很有设计头脑的编程人员。编程人员不仅仅是K代码的人而且要负责程序架构的设计。所以对程序员的要求就很高了。 简单设计的成功的一个基点是编程人员设计的逻辑结构简单并能根据需要来调整其逻辑结构,就是代码结构灵活,简单设计带来的另外一个变化就是会议会比较多,编程人员之间的交流就变的很重要。现在一般的中小型软件公司基本上都是采用简单设计的,除非那些很大型的软件公司。 
    总结,简单设计考验的是开发人员的能力。完全设计考验的是前期设计人员和整个项目组完整能力。(各种文档的编写,开发人员一定会要写一部分的。)


    2、设计变化和需求变化 


    开发人员最怕的是什么呢?设计变化,还是需求变化?我觉得需求变化是最最致命的。当你的一个项目数据库都定下来后,而且已经开发了若干个工作日,突然接到甲方公司提出,某个功能要改变,原先的需求分析要重新改,如果这个修改是涉及的数据库的表结构更改的话,那真是最致命的。这就意味着项目的某些部分得重新推倒重来,如果这个部分跟已完成的多个部分有牵连的话,那就后果更可怕了。所以当碰到这种情况发生,作为项目经理的你就应该考虑先查责任人,究竟是自己的需求分析做的不够好,还是客户在认同了需求分析后做出的修改,如果是后者的话,你完全可以要求客户对他的这个修改负责任!那么,呵呵,客户先生,对不起了,本次新增加的需求将归入另外一个版本。如果是改变前面某个需求的定义,那么说不定就要推倒重来了,不过这个时候到不用太在意,毕竟错的是客户。(项目正式开始前没有没有说清楚其需求)。所以,各位看客,在需求分析做好后,在开工之前一定要叫客户认可签字,并且在合同上要注明,当由客户原因引起的需求改变而造成开发成本的增加,客户要为此买单地。 
    如果在需求不变的情况之下,设计发生了变化,这个仅仅是我们内部之间的矛盾,商量一下就能解决。在简单设计中,因为前期的设计是不完整的,那么当进入任何一个新的模块进行开发时,都有可能引起设计的变化。开发人员的水平的高低就基本上决定了软件的好坏。


    3、代码编写

     
    当需求定下来数据库也定下来后, 其实我们就可以进行实质性的编码了,按照我的看法,一个人单独编程最好,能随时偷懒。(上网,和MM聊聊),但是现在的软件项目越来越大,工期也越来越紧,事实上我们一个小组里面,一般有3-5程序员,所以我们要强调团队合作性。那么你写的代码使得别人要能够看懂,我们必须在实际的编写代码过程中要有详细的编码规范,编码规范在很多书籍里面都提到过。但最起码以下的一些规范是我们必须要遵守的: 
     

    一)源程序文件结构: 
    每个程序文件应由标题、内容和附加说明三部分组成。 
    (1)标题:文件最前面的注释说明,其内容主要包括:程序名,作者,版权信息,简要说明 等,必要时应有更详尽的说明(将以此部分以空行隔开单独注释)。 
    (2)内容控件注册等函数应放在内容部分的最后,类的定义按 private 、 protected 、 pubilic 、 __pubished 的顺序,并尽量保持每一部分只有一个,各部分中按数据、函数、属性、事件的顺序。 
    (3)附加说明:文件末尾的补充说明,如参考资料等,若内容不多也可放在标题部分的最后。 
     

    二)界面设计风格的一致性: 
    由于采用可视化编程,所有的界面均与Win32方式类似,相应采用的控件等也大都为Windows操作系统下的标准控件,而且参考了其他一些市面上相关的企业内部管理的应用软件。 
    基于简单易操作的原则,贴近用户考虑,用户界面采用Windows风格的标准界面,操作方式亦同Windows风格,这样在实施过程,可以降低对客户的培训,也可以使用户容易上手,简单易学。 
     

    三)编辑风格: 
    (1)缩进:缩进以 Tab 为单位,一个 Tab 为四个空格大小。全局数据、函数 原型、标题、附加说明、函数说明、标号等均顶格书写。 
    (2)空格:数据和函数在其类型,修饰(如 __fastcall 等)名称之间适当空格并据情况对 齐。关键字原则上空一格,不论是否有括号,对语句行后加的注释应用适当空格与语句隔开并尽可能对齐。 
    (3)对齐:原则上关系密切的行应对齐,对齐包括类型、修饰、名称、参数等各部分对齐。 
    另每一行的长度不应超过屏幕太多,必要时适当换行。 
    (4)空行:程序文件结构各部分之间空两行,若不必要也可只空一行,各函数实现之间一般空两行。 
    (5)注释:对注释有以下三点要求: 
    A、必须是有意义; 
    B、必须正确的描述了程序; 
    C、必须是最新的。 
    注释必不可少,但也不应过多,以下是四种必要的注释: 
    标题、附加说明; 
    函数说明:对几乎每个函数都应有适当的说明,通常加在函数实现之前,在没有函数实现部分的情况下则加在函数原型前,其内容主要是函数的功能、目的、算法等说明,参数说明、返回 值说明等,必要时还要有一些如特别的软硬件要求等说明; 
    在代码不明晰或不可移植处应有少量说明; 
    及少量的其它注释。 
     

    四)命名规范: 
    坚持采用匈牙利变量命名惯例,所有标识符一律用英文或英文缩写,杜绝采用拼音,标识符中每个单词首字母大写,缩写词汇一般全部大写,只在必要时加“_”间隔词汇。


    4、BUG修补 


    程序出现了BUG谁来修补呢,嘿嘿嘿…… 
    最好的办法是谁编写谁修补,谁改坏谁修补。一个人改坏的代码一人去修。两个人一起改坏的代码两人一起修。


    5、开发人员的测试 


    开发人员的测试是保证代码能正常运行,在开发时候发现的错误往往比较容易修正。(另外一个好处就是没有人来骂你。因为只有你自己知道)。但是一旦软件到了测试小组那里出了问题,那么就多了很多时间来修正BUG,如果到了客户哪里才发现的BUG,那么时间就更长了,开发人员本身受到的压力也是到了最大话了。客户->公司->测试小组->开发人员。 这个完全是倒金字塔型的,承受能力差的一环很容易出事情的。 
    另外开发人员的测试除了保证代码能正常运行以外,还有一个很重要的方面就是要保证上次能正常运行的代码,这次还是能正常运行。如果做不到这点,那么BUG就不断的会出现,很多BUG也会反复出现。于是软件看上去就有修补不完的BUG了。如果出现这种情况,那么开发人员有必要再教育。一般公司教育的方式有四种。第一种,扣工资,第二种,加班,反复加班+精神攻击。 第三种,开除。第四种,调动人员来帮助那个出了麻烦的家伙。 但愿看这个文章的人不要受到前面三种教育。

    展开全文
  • 程序从入门到快速开发程序项目

    万次阅读 多人点赞 2018-08-28 23:01:25
    作者:谭东 备注:小程序只是突发灵感兴趣弄的,...然后有目标的进行实践,也就是要实现个你想要的小程序,这样边实践边学习才能够有疑问,才能够更快的理解和学习小程序开发。所以后续几天就开始小程序实践和学习...

    作者:谭东

    备注:小程序只是突发灵感兴趣弄的,并非专业研究小程序,其实小程序API并不多,不复杂,扩展无非就是JS了。

    最近用了大概两天左右的时间看了小程序的官方文档:https://mp.weixin.qq.com/cgi-bin/wx

    然后有目标的进行实践,也就是要实现个你想要的小程序,这样边实践边学习才能够有疑问,才能够更快的理解和学习小程序开发。所以后续几天就开始小程序实践和学习之旅了,期间也遇到了一些问题并且学到了很多基础知识和解决方案。接下来给大家讲解下小程序的开发基本知识和扩展知识。

    官方文档其实写的基本很详细了,我们先从工具开始说起。

    1、小程序开发者工具。

    这个工具集成了公众号网页调试和小程序调试两种开发模式。我这里使用了Beta版本,没有用正式版。因为我想体验使用其中的Git版本管理功能。下载地址:https://developers.weixin.qq.com/miniprogram/dev/devtools/beta.html

    下载安装好后,先要微信扫描登录。然后选择小程序项目。

    新建小程序项目。

    选择新建小程序的项目目录,AppID没有注册的话,可以先点击下面的使用测试号即可,不影响开发。

    大致的工具界面如下图,新版有版本管理。红色圈起来的为小程序项目的一个页面包含的元素:

    工具用起来很方便、简单、直接。详细用法就不说了,主要的功能大概说下。左侧是模拟器,可以模拟安卓手机和苹果手机的效果,因为有些小程序组件在安卓和苹果上显示是有区别的,大家可以注意下。圈红的为小程序一个页面的基本组成文件元素:xx.js、xx.wxml、xx.wxss、xx.json。其实就是有JS文件、HTML文件(xx.wxml)、CSS样式文件(xx.wxss)和配置文件(xx.json)组成,非常的容易理解。我们就是在使用小程序的组件、控件来绘制UI布局,主要是xx.wxml和xx.wxss文件。xx.js负责生命周期函数和事件处理,例如:点击事件、数据请求、数据绑定等等逻辑操作。

    我们在编写完后,可以点击工具栏上的预览按钮,扫描二维码在真机上体验,也可以直接用左侧的模拟器时时预览即可。

    看完了工具,我们看下基本开发的要素和需要注意的问题吧,以免新手再次重蹈覆辙。

    看下默认的新建后的结构:

    app.json是小程序全局配置文件,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等。

    大致代码结构如下:

    {
      "pages":[
        "pages/index/index",
        "pages/logs/logs"
      ],
      "window":{
        "backgroundTextStyle":"light",
        "navigationBarBackgroundColor": "#fff",
        "navigationBarTitleText": "WeChat",
        "navigationBarTextStyle":"black"
      }
    }

    pages是配置小程序所有页面,类似于注册清单。window是全局的窗口配置,如颜色、标题等等。当然每个页面也可以自己单独配置,就是页面名称.json文件。例如:page.json。不过需要注意的是,单独页面配置的json无需写window这个关键字,直接如下代码所示:

    {
      "backgroundTextStyle": "light",
      "navigationBarBackgroundColor": "#34495e",
      "navigationBarTitleText": "日记",
      "navigationBarTextStyle": "white",
      "enablePullDownRefresh": true,
      "backgroundColor": "#34495e"
    }

    那么再看工具配置文件project.config.json。

    通常大家在使用一个工具的时候,都会针对各自喜好做一些个性化配置,例如界面颜色、编译配置等等,当你换了另外一台电脑重新安装工具的时候,你还要重新配置。考虑到这点,小程序开发者工具在每个项目的根目录都会生成一个 project.config.json,你在工具上做的任何配置都会写入到这个文件,当你重新安装工具或者换电脑工作时,你只要载入同一个项目的代码包,开发者工具就自动会帮你恢复到当时你开发项目时的个性化配置,其中会包括编辑器的颜色、代码上传时自动压缩等等一系列选项。具体详细配置大家可以看小程序官方文档有详细介绍。

    还有一个app.wxss和app.js。这个app.wxss就是全局的样式文件,也就是css文件,当然和页面配置文件一样,每个页面可以单独写页面名称.wxss。

    WXSS 具有 CSS 大部分的特性,小程序在 WXSS 也做了一些扩充和修改。

    新增了尺寸单位。在写 CSS 样式时,开发者需要考虑到手机设备的屏幕会有不同的宽度和设备像素比,采用一些技巧来换算一些像素单位。WXSS 在底层支持新的尺寸单位 rpx ,开发者可以免去换算的烦恼,只要交给小程序底层来换算即可,由于换算采用的浮点数运算,所以运算结果会和预期结果有一点点偏差。

    提供了全局的样式和局部样式。和前边 app.json, page.json 的概念相同,你可以写一个 app.wxss 作为全局样式,会作用于当前小程序的所有页面,局部页面样式 page.wxss 仅对当前页面生效。

    此外 WXSS 仅支持部分 CSS 选择器

    再来看app.js,很明显是一个js文件。负责UI交互、数据绑定更新、网络请求、页面生命周期等等操作相关的都在这里。当然每个页面都有自己单独的.js文件,这个app.js可以做一些需要全局共享和操作的逻辑在里面。在这里可以调用微信小程序的很多API,也可以自己写js方法使用。

    那么我们看下一个页面的组成,基本上就是下图这些结构元素。有界面、有样式、有js交互、有配置。

    每新增一个页面都要在app.json里添加注册进去。

    一个.js文件里有生命周期的管理函数,可以在这里面做相应的操作。

    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function (options) {
        
      },
    
      /**
       * 生命周期函数--监听页面初次渲染完成
       */
      onReady: function () {
        
      },
    
      /**
       * 生命周期函数--监听页面显示
       */
      onShow: function () {
        
      },
    
      /**
       * 生命周期函数--监听页面隐藏
       */
      onHide: function () {
        
      },
    
      /**
       * 生命周期函数--监听页面卸载
       */
      onUnload: function () {
        
      },
    
      /**
       * 页面相关事件处理函数--监听用户下拉动作
       */
      onPullDownRefresh: function () {
        
      },
    
      /**
       * 页面上拉触底事件的处理函数
       */
      onReachBottom: function () {
        
      },
    
      /**
       * 用户点击右上角分享
       */
      onShareAppMessage: function () {
        
      }
    })

    我们看下最简单的一个index.wxml页面,可以当做是Html页面,只有一个text控件,里面的bindtap就是点击事件的绑定。

    <!--index.wxml-->
    <view class="container">
      <view class="usermotto">
        <text class="user-motto" bindtap='click'>{{motto}}</text>
      </view>
    </view>

    那么这个class就是index.wxss里的样式文件。里面的{{motto}}就是指向index.js里的data里定义的一个变量。小程序都是通过{{..}}两个大括号包括一个英文名字来进行变量绑定的。这样我们就可以动态更换里面的显示内容了。那么怎么更新内容呢?

    在js里使用下面的this.setData方式动态更新刷新数据:

    this.setData({ motto: "名字" })
    /**index.wxss**/
    .userinfo {
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    
    .userinfo-avatar {
      width: 128rpx;
      height: 128rpx;
      margin: 20rpx;
      border-radius: 50%;
    }
    
    .userinfo-nickname {
      color: #aaa;
    }
    
    .usermotto {
      margin-top: 200px;
    }

    再看下index.

    js文件。

    //index.js
    //获取应用实例
    const app = getApp()
    
    Page({
      data: {
        motto: 'Hello World',
      },
      
      //事件处理函数
      click: function() {
        wx.navigateTo({
          url: '../logs/logs'
        })
      },
        
    })

    Page函数是必须要有的,里面包含data:{  ... },用于放置数据、常量、变量等等。这里的click:function就是我们定义的点击事件。wx.navigateTo...方法就是小程序的官方API,具体其他API的用法和返回参数是什么可以看官方API文档,很详细。

    观察下,上面有个声明了app这个常量。这个就是app.js里拿到的全局管理调用app.js里的方法和常量用的。很多需要存储和全局读写、处理的都可以进行操作以及放置在app.js里。在 JavaScript 文件中声明的变量和函数只在该文件中有效;不同的文件中可以声明相同名字的变量和函数,不会互相影响。通过全局函数 getApp() 可以获取全局的应用实例,如果需要全局的数据可以在 App() 中设置。

    Page({
      data: { // 参与页面渲染的数据
        logs: []
      },
      onLoad: function () {
        // 页面渲染后执行
      }
    })

    小程序的组件和控件有很多,可以看做是Html的标签,对称方式使用。具体组件特性看官方文档:

    https://developers.weixin.qq.com/miniprogram/dev/component/

    为了让开发者可以很方便的调起微信提供的能力,例如获取用户信息、微信支付等等,小程序提供了很多 API 给开发者,例如:

    要获取用户的地理位置时,只需要:

    wx.getLocation({
      type: 'wgs84',
      success: (res) => {
        var latitude = res.latitude // 经度
        var longitude = res.longitude // 纬度
      }
    })

    调用微信扫一扫能力,只需要:

    wx.scanCode({
      success: (res) => {
        console.log(res)
      }
    })

    需要注意的是:多数 API 的回调都是异步,你需要处理好代码逻辑的异步问题。更多API说明和用法,看官方文档。

    https://developers.weixin.qq.com/miniprogram/dev/api/

    页面的生命周期,我之前说过了,比较重要,大家可以看下理解下。

    看下逻辑层需要注意的。除了页面的生命周期,还有页面的监听事件。onPullDownRefresh():监听用户下拉刷新事件。

    需要在app.json的window选项中或页面配置中开启enablePullDownRefresh。
    可以通过wx.startPullDownRefresh触发下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
    当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。

    onReachBottom():监听用户上拉触底事件。

    可以在app.json的window选项中或页面配置中设置触发距离onReachBottomDistance,默认为50px。
    在触发距离内滑动期间,本事件只会被触发一次。

    onPageScroll(Object):监听用户滑动页面事件。

    onShareAppMessage(Object):

    监听用户点击页面内转发按钮(<button> 组件 open-type="share")或右上角菜单“转发”按钮的行为,并自定义转发内容。

    注意:只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮。

    onTabItemTap(Object):点击 tab 时触发。

    Page.prototype.setData(Object data, Function callback):setData 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)。

    Object 以 key: value 的形式表示,将 this.data 中的 key 对应的值改变成 value。

    其中 key 可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如 array[2].message,a.b.c.d,并且不需要在 this.data 中预先定义。

    注意:

    直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。
    仅支持设置可 JSON 化的数据。
    单次设置的数据不能超过1024kB,请尽量避免一次设置过多的数据。
    请不要把 data 中任何一项的 value 设为 undefined ,否则这一项将不被设置并可能遗留一些潜在问题。

    接下来看下小程序里的路由、跳转。

    主要有这几种方式:

    这几种方式url都可以传递参数。

    wx.navigateTo:保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面。注意:目前页面路径最多只能十层。

    wx.redirectTo(OBJECT):关闭当前页面,跳转到应用内的某个页面。如果你想让页面没有返回按钮,不能返回的话,就用这个跳转方式吧。

    wx.reLaunch(OBJECT):关闭所有页面,打开到应用内的某个页面。

    wx.switchTab(OBJECT):跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。

    wx.navigateBack(OBJECT):关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。

    注意:

    1、navigateTo, redirectTo 只能打开非 tabBar 页面。
    2、switchTab 只能打开 tabBar 页面。
    3、reLaunch 可以打开任意页面。
    4、页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
    5、调用页面路由带的参数可以在目标页面的onLoad中获取。

    再看下模块化。

    可以将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。模块只有通过 module.exports 或者 exports 才能对外暴露接口。

    需要注意的是:

    exports 是 module.exports 的一个引用,因此在模块里边随意更改 exports 的指向会造成未知的错误。所以更推荐开发者采用 module.exports 来暴露模块接口,除非你已经清晰知道这两者的关系。小程序目前不支持直接引入 node_modules , 开发者需要使用到 node_modules 时候建议拷贝出相关的代码到小程序的目录中。

    // common.js
    function sayHello(name) {
      console.log(`Hello ${name} !`)
    }
    function sayGoodbye(name) {
      console.log(`Goodbye ${name} !`)
    }
    
    module.exports.sayHello = sayHello
    exports.sayGoodbye = sayGoodbye

    ​在需要使用这些模块的文件中,使用 require(path) 将公共代码引入:

    var common = require('common.js')
    Page({
      helloMINA: function() {
        common.sayHello('MINA')
      },
      goodbyeMINA: function() {
        common.sayGoodbye('MINA')
      }
    })

    注意:require 暂时不支持绝对路径。

    接下来看下小程序的视图层,也就是wxml和wxss。

    框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。将逻辑层的数据反应成视图,同时将视图层的事件发送给逻辑层。

    WXML(WeiXin Markup language) 用于描述页面的结构。

    WXS(WeiXin Script) 是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。

    WXSS(WeiXin Style Sheet) 用于描述页面的样式。

    组件(Component)是视图的基本组成单元。

    这里挑几个比较重要的来说。首先是列表渲染,就是我们想实现一个List列表展示的时候,要进行List数据绑定,item数据绑定、可能还会涉及到模板和数据传递等等。

    列表渲染:

    <!--wxml-->
    <view wx:for="{{array}}"> {{item}} </view>
    // page.js
    Page({
      data: {
        array: [1, 2, 3, 4, 5]
      }
    })

    在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item。

    <view wx:for="{{array}}">
      {{index}}: {{item.message}}
    </view>

    使用 wx:for-item 可以指定数组当前元素的变量名,

    使用 wx:for-index 可以指定数组当前下标的变量名:

    <view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
      {{idx}}: {{itemName.message}}
    </view>

    wx:for 也可以嵌套。类似 block wx:if,也可以将 wx:for 用在<block/>标签上,以渲染一个包含多节点的结构块。例如:

    <block wx:for="{{[1, 2, 3]}}">
      <view> {{index}}: </view>
      <view> {{item}} </view>
    </block>

    如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 <input/> 中的输入内容,<switch/> 的选中状态),需要使用 wx:key 来指定列表中项目的唯一的标识符。

    wx:key 的值以两种形式提供:

    字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
    保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字,如:
    当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。

    如不提供 wx:key,会报一个 warning, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。

    条件渲染:

    <!--wxml-->
    <view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
    <view wx:elif="{{view == 'APP'}}"> APP </view>
    <view wx:else="{{view == 'MINA'}}"> MINA </view>
    // page.js
    Page({
      data: {
        view: 'MINA'
      }
    })

    在框架中,使用 wx:if="{{condition}}" 来判断是否需要渲染该代码块。

    因为 wx:if 之中的模板也可能包含数据绑定,所以当 wx:if 的条件值切换时,框架有一个局部渲染的过程,因为它会确保条件块在切换时销毁或重新渲染。同时 wx:if 也是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。

    相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。

    一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。

    还可能会涉及到模板template,可以在模板中定义代码片段,然后在不同的地方调用。

    使用 name 属性,作为模板的名字。然后在<template/>内定义代码片段,如:

    <!--
      index: int
      msg: string
      time: string
    -->
    <template name="msgItem">
      <view>
        <text> {{index}}: {{msg}} </text>
        <text> Time: {{time}} </text>
      </view>
    </template>

    使用 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入,如:

    <template is="msgItem" data="{{...item}}"/>
    Page({
      data: {
        item: {
          index: 0,
          msg: 'this is a template',
          time: '2016-09-15'
        }
      }
    })

    is 属性可以使用 Mustache 语法,来动态决定具体需要渲染哪个模板:

    <template name="odd">
      <view> odd </view>
    </template>
    <template name="even">
      <view> even </view>
    </template>
    
    <block wx:for="{{[1, 2, 3, 4, 5]}}">
    	<template is="{{item % 2 == 0 ? 'even' : 'odd'}}"/>
    </block>

    模板拥有自己的作用域,只能使用 data 传入的数据以及模版定义文件中定义的 <wxs /> 模块。

    另外,target(触发事件的源组件)和currentTarget(事件绑定的当前组件)也比较重要,大家可以自行看例子和文档学习。

    dataset:在组件中可以定义数据,这些数据将会通过事件传递给 SERVICE。 书写方式: 以data-开头,多个单词由连字符-链接,不能有大写(大写会自动转成小写)如data-element-type,最终在 event.currentTarget.dataset 中会将连字符转成驼峰elementType。

    <view data-alpha-beta="1" data-alphaBeta="2" bindtap="bindViewTap"> DataSet Test </view>
    Page({
      bindViewTap:function(event){
        event.currentTarget.dataset.alphaBeta === 1 // - 会转为驼峰写法
        event.currentTarget.dataset.alphabeta === 2 // 大写会转为小写
      }
    })

    小程序的引用,如引用外部css文件、引入js文件、引入wxml模板文件等等。

    WXML 提供两种文件引用方式import和include。

    import可以在该文件中使用目标文件定义的template,如:在 item.wxml 中定义了一个叫item的template:

    <!-- item.wxml -->
    <template name="item">
      <text>{{text}}</text>
    </template>

    在 index.wxml 中引用了 item.wxml,就可以使用item模板:

    <import src="item.wxml"/>
    <template is="item" data="{{text: 'forbar'}}"/>

    import 有作用域的概念,即只会 import 目标文件中定义的 template,而不会 import 目标文件 import 的 template。

    include 可以将目标文件除了 <template/> <wxs/> 外的整个代码引入,相当于是拷贝到 include 位置,如:

    <!-- index.wxml -->
    <include src="header.wxml"/>
    <view> body </view>
    <include src="footer.wxml"/>
    <!-- header.wxml -->
    <view> header </view>
    <!-- footer.wxml -->
    <view> footer </view>

    再讲一个wxs文件,不太常用。WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。

    注意:
    1、wxs 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。
    2、wxs 与 javascript 是不同的语言,有自己的语法,并不和 javascript 一致。
    3、wxs 的运行环境和其他 javascript 代码是隔离的,wxs 中不能调用其他 javascript 文件中定义的函数,也不能调用小程序提供的API。
    4、wxs 函数不能作为组件的事件回调。
    5、由于运行环境的差异,在 iOS 设备上小程序内的 wxs 会比 javascript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。
    以下是一些使用 WXS 的简单示例。

    页面渲染:

    <!--wxml-->
    <wxs module="m1">
    var msg = "hello world";
    
    module.exports.message = msg;
    </wxs>
    
    <view> {{m1.message}} </view>

    页面输出:

    hello world

    数据处理:

    // page.js
    Page({
      data: {
        array: [1, 2, 3, 4, 5, 1, 2, 3, 4]
      }
    })
    <!--wxml-->
    <!-- 下面的 getMax 函数,接受一个数组,且返回数组中最大的元素的值 -->
    <wxs module="m1">
    var getMax = function(array) {
      var max = undefined;
      for (var i = 0; i < array.length; ++i) {
        max = max === undefined ? 
          array[i] : 
          (max >= array[i] ? max : array[i]);
      }
      return max;
    }
    
    module.exports.getMax = getMax;
    </wxs>
    
    <!-- 调用 wxs 里面的 getMax 函数,参数为 page.js 里面的 array -->
    <view> {{m1.getMax(array)}} </view>

    页面会输出5。

    WXS 代码可以编写在 wxml 文件中的 <wxs> 标签内,或以 .wxs 为后缀名的文件内。

    每一个 .wxs 文件和 <wxs> 标签都是一个单独的模块。每个模块都有自己独立的作用域。即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见。一个模块要想对外暴露其内部的私有变量与函数,只能通过 module.exports 实现。

    可以直接创建 .wxs 文件,在其中直接编写 WXS 脚本。

    var foo = "'hello world' from comm.wxs";
    var bar = function(d) {
      return d;
    }
    module.exports = {
      foo: foo,
      bar: bar
    };

    在.wxs文件里面编写了 WXS 代码。该 .wxs 文件可以被其他的 .wxs 文件 或 WXML 中的 <wxs> 标签引用。

    每个 wxs 模块均有一个内置的 module 对象。exports:通过该属性,可以对外共享本模块的私有变量与函数。

    // /pages/tools.wxs
    
    var foo = "'hello world' from tools.wxs";
    var bar = function (d) {
      return d;
    }
    module.exports = {
      FOO: foo,
      bar: bar,
    };
    module.exports.msg = "some msg";
    <!-- page/index/index.wxml -->
    
    <wxs src="./../tools.wxs" module="tools" />
    <view> {{tools.msg}} </view>
    <view> {{tools.bar(tools.FOO)}} </view>

    页面输出:

    some msg
    'hello world' from tools.wxs

    在.wxs模块中引用其他 wxs 文件模块,可以使用 require 函数。

    引用的时候,要注意如下几点:

    1、只能引用 .wxs 文件模块,且必须使用相对路径。
    2、wxs 模块均为单例,wxs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个 wxs 模块对象。
    3、如果一个 wxs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。

    module 属性是当前 <wxs> 标签的模块名。在单个 wxml 文件内,建议其值唯一。有重复模块名则按照先后顺序覆盖(后者覆盖前者)。不同文件之间的 wxs 模块名不会相互覆盖。module 属性值的命名必须符合下面两个规则:

    1、首字符必须是:字母(a-zA-Z),下划线(_)。
    2、剩余字符可以是:字母(a-zA-Z),下划线(_), 数字(0-9)。

    src 属性可以用来引用其他的 wxs 文件模块。引用的时候,要注意如下几点:

    1、只能引用 .wxs 文件模块,且必须使用相对路径。
    2、wxs 模块均为单例,wxs 模块在第一次被引用时,会自动初始化为单例对象。多个页面,多个地方,多次引用,使用的都是同一个 wxs 模块对象。
    3、如果一个 wxs 模块在定义之后,一直没有被引用,则该模块不会被解析与运行。

    注意:
    1、<wxs> 模块只能在定义模块的 WXML 文件中被访问到。使用 <include> 或 <import> 时,<wxs> 模块不会被引入到对应的 WXML 文件中。
    2、<template> 标签中,只能使用定义该 <template> 的 WXML 文件中定义的 <wxs> 模块。

    再看下官方给出的小程序性能优化建议。

    setData 是小程序开发中使用最频繁的接口,也是最容易引发性能问题的接口。在介绍常见的错误用法前,先简单介绍一下 setData 背后的工作原理。

    小程序的视图层目前使用 WebView 作为渲染载体,而逻辑层是由独立的 JavascriptCore 作为运行环境。在架构上,WebView 和 JavascriptCore 都是独立的模块,并不具备数据直接共享的通道。当前,视图层和逻辑层的数据传输,实际上通过两边提供的 evaluateJavascript 所实现。即用户传输的数据,需要将其转换为字符串形式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立环境。而 evaluateJavascript 的执行会受很多方面的影响,数据到达视图层并不是实时的。

    常见的 setData 操作错误:
    1. 频繁的去 setData。

    在我们分析过的一些案例里,部分小程序会非常频繁(毫秒级)的去setData,其导致了两个后果:Android 下用户在滑动时会感觉到卡顿,操作反馈延迟严重,因为 JS 线程一直在编译执行渲染,未能及时将用户操作事件传递到逻辑层,逻辑层亦无法及时将操作处理结果及时传递到视图层;
    渲染有出现延时,由于 WebView 的 JS 线程一直处于忙碌状态,逻辑层到页面层的通信耗时上升,视图层收到的数据消息时距离发出时间已经过去了几百毫秒,渲染的结果并不实时;
    2. 每次 setData 都传递大量新数据。

    由setData的底层实现可知,我们的数据传输实际是一次 evaluateJavascript 脚本过程,当数据量过大时会增加脚本的编译执行时间,占用 WebView JS 线程,

    3. 后台态页面进行 setData。

    当页面进入后台态(用户不可见),不应该继续去进行setData,后台态页面的渲染用户是无法感受的,另外后台态页面去setData也会抢占前台页面的执行。

    图片资源:
    目前图片资源的主要性能问题在于大图片和长列表图片上,这两种情况都有可能导致 iOS 客户端内存占用上升,从而触发系统回收小程序页面。

    图片对内存的影响:
    在 iOS 上,小程序的页面是由多个 WKWebView 组成的,在系统内存紧张时,会回收掉一部分 WKWebView。从过去我们分析的案例来看,大图片和长列表图片的使用会引起 WKWebView 的回收。

    图片对页面切换的影响:
    除了内存问题外,大图片也会造成页面切换的卡顿。我们分析过的案例中,有一部分小程序会在页面中引用大图片,在页面后退切换中会出现掉帧卡顿的情况。当前我们建议开发者尽量减少使用大图片资源。

    代码包大小的优化:
    小程序一开始时代码包限制为 1MB,但我们收到了很多反馈说代码包大小不够用,经过评估后我们放开了这个限制,增加到 2MB 。代码包上限的增加对于开发者来说,能够实现更丰富的功能,但对于用户来说,也增加了下载流量和本地空间的占用。开发者在实现业务逻辑同时也有必要尽量减少代码包的大小,因为代码包大小直接影响到下载速度,从而影响用户的首次打开体验。除了代码自身的重构优化外,还可以从这两方面着手优化代码大小:

    控制代码包内图片资源:
    小程序代码包经过编译后,会放在微信的 CDN 上供用户下载,CDN 开启了 GZIP 压缩,所以用户下载的是压缩后的 GZIP 包,其大小比代码包原体积会更小。 但我们分析数据发现,不同小程序之间的代码包压缩比差异也挺大的,部分可以达到 30%,而部分只有 80%,而造成这部分差异的一个原因,就是图片资源的使用。GZIP 对基于文本资源的压缩效果最好,在压缩较大文件时往往可高达 70%-80% 的压缩率,而如果对已经压缩的资源(例如大多数的图片格式)则效果甚微。

    及时清理没有使用到的代码和资源:
    在日常开发的时候,我们可能引入了一些新的库文件,而过了一段时间后,由于各种原因又不再使用这个库了,我们常常会只是去掉了代码里的引用,而忘记删掉这类库文件了。目前小程序打包是会将工程下所有文件都打入代码包内,也就是说,这些没有被实际使用到的库文件和资源也会被打入到代码包里,从而影响到整体代码包的大小。

    下面将会讲解一些开发中遇到的问题:

    列表绑定渲染数据、跳转传值、小程序的工具调试使用、小程序授权弹窗、小程序客服反馈、小程序支付、小程序获取unionId和openId、小程序第三方框架、UI库等。

     

     

    这个是开源share的,github地址:https://github.com/jaychou2012/wx_note

     

     

    持续更新中,敬请关注... ...

    展开全文
  • 软件开发流程与模式

    万次阅读 2018-01-26 10:18:25
    软件开发角色与流程软件生命周期: 制定计划,需求分析,设计,编码实现,测试,运行维护模型与演进主要模型介绍1. 边做边改模型(Build-and-Fix Model) 其实现在许多产品实际都是使用的“边做边改”模型来开发的...

    软件开发角色与流程

    软件生命周期: 制定计划,需求分析,设计,编码实现,测试,运行维护




    模型与演进



    主要模型介绍

    1. 边做边改模型(Build-and-Fix Model)
      其实现在许多产品实际都是使用的“边做边改”模型来开发的,特别是很多小公司产品周期压缩的太短。在这种模型中,既没有规格说明,也没有经过设计,软件随着客户的需要一次又一次地不断被修改。
      在这个模型中,开发人员拿到项目立即根据需求编写程序,调试通过后生成软件的第一个版本。在提供给用户使用后,如果程序出现错误,或者用户提出新的要求,开发人员重新修改代码,直到用户和测试等等满意为止。
      这是一种类似作坊的开发方式,边做边改模型的优点毫无疑问就是前期出成效快。
      对编写逻辑不需要太严谨的小程序来说还可以对付得过去,但这种方法对任何规模的开发来说都是不能令人满意的,其主要问题在于:
      1) 缺少规划和设计环节,软件的结构随着不断的修改越来越糟,导致无法继续修改;
      2) 忽略需求环节,给软件开发带来很大的风险;
      3) 没有考虑测试和程序的可维护性,也没有任何文档,软件的维护十分困难。


    2. 瀑布模型 - Waterfall model
    (1). 起源与定义:
    1970  W.W.Royce  温斯顿·罗伊斯 , 直到80年代都还是一直被广泛采用的模型。
    瀑布模型将软件生命周期划分为制定计划、需求分析、软件设计、程序编写、软件测试和运行维护等六个基本活动,并且规定了它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落。
      在瀑布模型中,软件开发的各项活动严格按照线性方式进行,当前活动接受上一项活动的工作结果,实施完成所需的工作内容。当前活动的工作结果需要进行验证,如验证通过,则该结果作为下一项活动的输入,继续进行下一项活动,否则返回修改。
      瀑布模型优点是严格遵循预先计划的步骤顺序进行,一切按部就班比较严谨。


    (2)优劣与评价
    瀑布式开发是一种老旧的计算机软件开发方法。
    瀑布模型式是最典型的预见性的方法,严格遵循预先计划的需求分析、设计、编码、集成、测试、维护的步骤顺序进行。
    步骤成果作为衡量进度的方法,例如需求规格,设计文档,测试计划和代码审阅等等。 


    瀑布式的主要的问题是它的严格分级导致的自由度降低,项目早期即作出承诺导致对后期需求的变化难以调整,
    代价高昂。瀑布式方法在需求不明并且在项目进行过程中可能变化的情况下基本是不可行的。 
    瀑布模型强调文档的作用,并要求每个阶段都要仔细验证。但是,这种模型的线性过程太理想化,已不再适合现代的软件开发模式,几乎被业界抛弃,其主要问题在于:
      1) 各个阶段的划分完全固定,阶段之间产生大量的文档,极大地增加了工作量;
      2) 由于开发模型是线性的,用户只有等到整个过程的末期才能见到开发成果,从而增加了开发的风险;
      3) 早期的错误可能要等到开发后期的测试阶段才能发现,进而带来严重的后果。
      4) 各个软件生命周期衔接花费时间较长,团队人员交流成本大。
      5) 瀑布式方法在需求不明并且在项目进行过程中可能变化的情况下基本是不可行的。
    优点:严格遵循预先计划的步骤顺序进行,一切按部就班比较严谨。
    (1)为项目提供了按阶段分的检查点
    (2)当完成一个阶段后,只需要去关注后续阶段
    (3)可在迭代模型中应用瀑布模型
    缺点:缺乏灵活性,太过线性理想化,不适合现代软件开发
    (1)各个阶段的划分完全固定,阶段之间产生大量的文档,极大地增加了工作量;
    (2)由于开发模型是线性的,用户只有等到整个过程的末期才能见到开发成果,从而增加了开发的风险;
    (3)早期的错误可能要等到开发后期的测试阶段才能发现,进而带来严重的后果。
    (4)各个软件生命周期衔接花费时间较长,团队人员交流成本大。
    (5)瀑布式方法在需求不明并且在项目进行过程中可能变化的情况下基本是不可行的

    3. 快速原型模型 Rapid Prototype Model
    (1). 起源与定义:
    快速原型模型(Rapid Prototype Model)
      快速原型模型的第一步是建造一个快速原型,实现客户或未来的用户与系统的交互,用户或客户对原型进行评价,进一步细化待开发软件的需求。通过逐步调整原型使其满足客户的要求,开发人员可以确定客户的真正需求是什么;第二步则在第一步的基础上开发客户满意的软件产品。
    (2)优劣与评价
      显然,快速原型方法可以克服瀑布模型的缺点,减少由于软件需求不明确带来的开发风险,具有显著的效果。
      快速原型的关键在于尽可能快速地建造出软件原型,一旦确定了客户的真正需求,所建造的原型将被丢弃。因此,原型系统的内部结构并不重要,重要的是必须迅速建立原型,随之迅速修改原型,以反映客户的需求。
      快速原型模型有点整合“边做边改”与“瀑布模型”优点的意味。
    优点:
    (1)生命周期短
    (2)整合“边做边改”与“瀑布模型”优点
    (3)减少软件需求不明确带来的开发风险
    (4)适用于小型、交互型的系统,大型系统的某些部分
    缺点:
    (1)可能导致系统设计差、效率低、难以维护

    (3) 基于已有平台开发



    4. 增量模型(Incremental-Model)
    (1). 起源与定义
    在增量模型中,软件被作为一系列的增量构件来设计、实现、集成和测试,每一个构件是由多种相互作用的模块所形成的提供特定功能的代码片段构成。
    增量模型在各个阶段并不交付一个可运行的完整产品,而是交付满足客户需求的一个子集的可运行产品。整个产品被分解成若干个构件,开发人员逐个构件地交付产品,这样做的好处是软件开发可以较好地适应变化,客户可以不断地看到所开发的软件,从而降低开发风险。但是,增量模型也存在以下缺陷:
    (1) 由于各个构件是逐渐并入已有的软件体系结构中的,所以加入构件必须不破坏已构造好的系统部分,这需要软件具备开放式的体系结构。
    (2) 在开发过程中,需求的变化是不可避免的。增量模型的灵活性可以使其适应这种变化的能力大大优于瀑布模型和快速原型模型,但也很容易退化为边做边改模型,从而使软件过程的控制失去整体性。
    在使用增量模型时,第一个增量往往是实现基本需求的核心产品。核心产品交付用户使用后,经过评价形成下一个增量的开发计划,它包括对核心产品的修改和一些新功能的发布。这个过程在每个增量发布后不断重复,直到产生最终的完善产品。
    例如,使用增量模型开发字处理软件。可以考虑,第一个增量发布基本的文件管理、编辑和文档生成功能,第二个增量发布更加完善的编辑和文档生成功能,第三个增量实现拼写和文法检查功能,第四个增量完成高级的页面布局功能。
    (2)优劣与评价
    优点:
    (1)人员分配灵活,一开始不需要投入大量人力
    (2)先推出核心的产品,在后续增加相应的功能
    (3)增量能够有计划的管理技术风险
    (4)适用于需求经常变更的软件开发过程
    缺点:
    (1)如果增量包之间存在相交的情况未很好的处理,则必须做全盘的系统分析


    5.  迭代式开发 - stagewise model   -- Iterative 
    (1). 起源与定义:
    迭代式开发也被称作迭代增量式开发或迭代进化式开发,是一种与传统的瀑布式开发相反的软件开发过程,它弥补了传统开发方式中的一些弱点,具有更高的成功率和生产率。


     教学中,对迭代和版本的区别,可理解如下: 迭代一般指某版本的生产过程,包括从需求分析到测试完成; 版本一般指某阶段软件开发的结果,一个可交付使用的产品。


    在迭代式开发方法中,整个开发工作被组织为一系列的短小的、
    固定长度(如3周)的小项目,被称为一系列的迭代。
    每一次迭代都包括了需求分析、设计、实现与测试。
    采用这种方法,开发工作可以在需求被完整地确定之前启动,
    并在一次迭代中完成系统的一部分功能或业务逻辑的开发工作。
    再通过客户的反馈来细化需求,并开始新一轮的迭代。




    (2)优劣与评价
    迭代式开发的优点:
      1、降低风险
      2、得到早期用户反馈
      3、持续的测试和集成
      4、使用变更
      5、提高复用性
    优点:
    (1)降低了在一个增量上的开支风险。如果开发人员重复某个迭代,那么损失只是这一个开发有误的迭代的花费。
    (2)降低了产品无法按照既定进度进入市场的风险。通过在开发早期就确定风险,可以尽早来解决而不至于在开发后期匆匆忙忙。
    (3)加快了整个开发工作的进度。因为开发人员清楚问题的焦点所在,他们的工作会更有效率。
    (4)由于用户的需求并不能在一开始就作出完全的界定,它们通常是在后续阶段中不断细化的。因此,迭代过程这种模式使适应需求的变化会更容易些。因此复用性更高


    6. 螺旋模型(Spiral-Model)
    (1). 起源与定义
    1988年,巴利·玻姆(Barry Boehm)正式发表了软件系统开发的“螺旋模型”,它将瀑布模型和快速原型模型结合起来,强调了其他模型所忽视的风险分析,特别适合于大型复杂的系统。
    螺旋模型沿着螺线进行若干次迭代,图中的四个象限代表了以下活动:
    (1)制定计划:确定软件目标,选定实施方案,弄清项目开发的限制条件;
    (2)风险分析:分析评估所选方案,考虑如何识别和消除风险;
    (3)实施工程:实施软件开发和验证;
    (4)客户评估:评价开发工作,提出修正建议,制定下一步计划。
    螺旋模型由风险驱动,强调可选方案和约束条件从而支持软件的重用,有助于将软件质量作为特殊目标融入产品开发之中。但是,螺旋模型也有一定的限制条件,具体如下:
    (1)螺旋模型强调风险分析,但要求许多客户接受和相信这种分析,并做出相关反应是不容易的,因此,这种模型往往适应于内部的大规模软件开发。
    (2)如果执行风险分析将大大影响项目的利润,那么进行风险分析毫无意义,因此,螺旋模型只适合于大规模软件项目。
    (3)软件开发人员应该擅长寻找可能的风险,准确地分析风险,否则将会带来更大的风险
    一个阶段首先是确定该阶段的目标,完成这些目标的选择方案及其约束条件,然后从风险角度分析方案的开发策略,努力排除各种潜在的风险,有时需要通过建造原型来完成。如果某些风险不能排除,该方案立即终止,否则启动下一个开发步骤。最后,评价该阶段的结果,并设计下一个阶段。
    螺旋模型很大程度上是一种风险驱动的方法体系,因为在每个阶段之前及经常发生的循环之前,都必须首先进行风险评估。



    7,敏捷开发模型(Agile-Development-Model)
    2001
    敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成果都经过测试,具备集成和可运行的特征。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。
    敏捷开发小组主要的工作方式:
    (1)作为一个整体工作;
    (2)按短迭代周期工作;
    (3)每次迭代交付一些成果,关注业务优先级,检查与调整。
    敏捷开发的4个核心思想:
    (1)强调面对面的沟通,人和人的相互交流胜于任何流程和工具
    (2)把精力集中在可执行的程序上,可以运行的产品胜于编制综合性文档,强调了原型、模型、demo等的重要性
    (3)团队合作和团队激励,合作胜于谈判,敏捷开发能将需求、开发、测试等全部团队成员融合成一个整体,大家都是一条线上的蚂蚱
    (4)超强的适应能力,适应变化胜于按部就班,敏捷开发的特点就是快速
    敏捷软件开发要注意项目规模,规模增长,团队交流成本就上去了,因此敏捷软件开发暂时适合不是特别大的团队开发,比较适合一个组的团队使用。


    敏捷开发模式有许多不同的形式,包括:Scrum,Crystal,Extreme Programming(XP)和Feature-Driven Development(FDD))。它通过迭代开发,关注互动沟通等方法来降低软件开发过程中的风险,同时也可以减少在开发中的资源消耗。好处是通过早期发现和修复缺陷来提高开发的效率。但这种模式比较依赖用户的信息反馈,而且这种模式比较适用于小规模的软件开发公司,习惯于“瀑布法”的程序员,管理层和组织可能难以适应敏捷。


    8. 演化模型(Evolutionary-Model)
    主要针对事先不能完整定义需求的软件开发。用户可以给出待开发系统的核心需求,并且当看到核心需求实现后,能够有效地提出反馈,以支持系统的最终设计和实现。软件开发人员根据用户的需求,首先开发核心系统。当该核心系统投入运行后,用户试用之,完成他们的工作,并提出精化系统、增强系统能力的需求。软件开发人员根据用户的反馈,实施开发的迭代过程。第一迭代过程均由需求、设计、编码、测试、集成等阶段组成,为整个系统增加一个可定义的、可管理的子集。
    在开发模式上采取分批循环开发的办法,每循环开发一部分的功能,它们成为这个产品的原型的新增功能。于是,设计就不断地演化出新的系统。 实际上,这个模型可看作是重复执行的多个“瀑布模型”。
    “演化模型”要求开发人员有能力把项目的产品需求分解为不同组,以便分批循环开发。这种分组并不是绝对随意性的,而是要根据功能的重要性及对总体设计的基础结构的影响而作出判断。有经验指出,每个开发循环以六周到八周为适当的长度。


    9,喷泉模型(Fountain-Model)
    以用户需求为动力,以对象为驱动的模型,主要用于采用对象技术的软件开发项目
    喷泉模型与传统的结构化生存期比较,具有更多的增量和迭代性质,生存期的各个阶段可以相互重叠和多次反复,而且在项目的整个生存期中还可以嵌入子生存期。就像水喷上去又可以落下来,可以落在中间,也可以落在最底部。
    优点:
    (1)可以提高软件项目开发效率,节省开发时间,适用于面向对象的软件开发过程
    缺点:
    (1)由于喷泉模型在各个开发阶段是重叠的,因此在开发过程中需要大量的开发人员,不利于项目的管理
    (2)这个模型要求严格管理文档,使得审核难度加大,尤其是面对随时加入各种需求


    10,智能模型(四代技术4GL)
    智能模型拥有一组工具(如数据查询、报表生成、数据处理、屏幕定义、代码生成、高层图形功能及电子表格等),每个工具都能使开发人员在高层次上定义软件的某些特性,并把开发人员定义的这些软件自动地生成为源代码。这种方法需要四代语言(4GL)的支持。4GL不同于三代语言,其主要特征是用户界面极端友好,即使没有受过训练的非专业程序员,也能用它编写程序;它是一种声明式、交互式和非过程性编程语言。4GL还具有高效的程序代码、智能缺省假设、完备的数据库和应用程序生成器。目前市场上流行的4GL(如Foxpro等)都不同程度地具有上述特征。但4GL目前主要限于事务信息系统的中、小型应用程序的开发。


    11,混合模型(Hybrid-Model)
    过程开发模型又叫混合模型(hybrid model),或元模型(meta-model),把几种不同模型组合成一种混合模型,它允许一个项目能沿着最有效的路径发展,这就是过程开发模型(或混合模型)。实际上,一些软件开发单位都是使用几种不同的开发方法组成他们自己的混合模型。
     
    12.快速应用开发模式- RAD model
    快速应用开发模式是一个比较精简的软件开发流程,可以以低投资成本生产高质量的软件。这种RAD流程可以使开发人员快速适应不断变化的市场需求。快速调整的能力可以帮助企业节省开发成本。快速应用程序开发模式分为四个阶段:需求规划,用户设计,构建和切换。重复用户设计和施工阶段,直到满足用户的所有要求。
    RAD对于具有明确定义的业务目标及用户组的开发项目最有效,比较适用于一些中小型软件开发项目,或者是开发时间比较紧迫的软件项目。然而,它需要技术人员具有丰富开发经验,以及要非常了解用户的核心需求。



    DevOps部署模式增强了软件开发部门之间的协作,如开发,测试和运营。它着重于改进软件的上市时间,降低新版本的故障率,缩短BUG修复的交付时间,优先考虑最小的中断以及最大的可靠性等。
    使用DevOps部署模式对提高客户满意度,提高产品质量,提高员工的生产力和效率得益等方面非常有用。但DevOps也有一些缺点:
    有些客户不想持续更新他们的软件
    一些行业在允许进入运营阶段之前,需要进行大量测试
    不同部门使用的不同环境可能导致软件开发过程中一些问题不会显现出来
    一些质量属性需要人为的相互作用,这会减慢软件的交付流程

    14. V 模型
     V模型是瀑布模型的变形,与传统的瀑布模型相比,该模型更加强调测试过程应如何与分析设计等过程相关联。如图:V模型中顶点左侧和右侧之间的连线表示如果在测试和确认过程中发现问题,那么左侧的过程要重新执行。


    最后, 来一张连连看


    比对与应用

    在实际的使用中, 基本上很少使用单一的方式, 一般都是综合起来使用。根据项目、团队等状况统筹选取适合自己团队和项目的模式。

    Model 说明 优点 缺点 适用
    1 Build-and-Fix 无规格,无设计,客户需要就修改 前期出成效快 1. 修改困难 2.维护性差 不太严谨的小程序
    2 Waterfall 严格遵循预先计划的需求分析、设计、
    编码、集成、测试、维护
    1. 简单
    2.  阶段明确易控制
    1. 自由度较低低
    2. 变化成本高,风险大
    3.不支持用户参与
    需求易于完善定义且不易变更的软件系统
    3 V model 强调测试过程应如何与分析设计等过程相关联 同Waterfall 相对Waterfall,可以提前发现风险 需求易于完善定义且不易变更的软件系统
    4 Prototype 建造一个快速原型,调整修改开发 1. 整合Build-and-Fix和Waterfall优点
    2.减少需求不明确风险
    1. 系统设计差
    2. 效率低
    3. 难以维护
    1.小型,交互式系统。
    或是大型系统的部分.
    2.需求复杂、难以确定、动态变化
    5 Iterative 整个开发工作被组织为一系列的短小的、
    固定长度(如3周)的小项目,每一次迭代都包括了需求分析、设计、实现与测试
    1. 降低风险
    2.得到用户早期反馈和变更
    3. 高复用性
    需要高素质的项目管理者
    高技术水平的开发团队
    需求难以确定、不断变更的软件系统
    6 Incremental 软件被作为一系列的增量构件来设计、实现、集成和测试,每一个构件是由多种相互作用的模块所形成的提供特定功能的代码片段构成。 1. 降低风险
    2.人员分配灵活
    3. 先推出核心产品
    1. 容易退化为边做边改
    2. 增量包之间的相交难处理
    技术风险较大、用户需求较为稳定的软件系统
    7 Spiral 瀑布模型和快速原型模型结合起来,螺旋模型沿着螺线进行若干次迭代:制定计划,风险分析,实施工程,客户评估 强调了其他模型所忽视的风险分析 软件开发人员应该擅长寻找可能的风险 1.内部的大规模软件开发
    2.需求难以获取和确定、软件开发风险较大的软件系统
    8 Agile 以人为核心、迭代、循序渐进。把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态 1. 市场快速反应能力
    2. 前期满意度高
    1. 需要项目中存在经验较强的人 1. 团队人数不能太多
    2. 经常变更,高风险的项目
    3. 开发人员可以参与决策
    4.项目周期短
    9 DevOps 增强了软件开发部门之间的协作,如开发,测试和运营。它着重于改进软件的上市时间,降低新版本的故障率,缩短BUG修复的交付时间,优先考虑最小的中断以及最大的可靠性

    DevOps是在整个IT价值流中实施精益原则的结果。IT价值流将开发延伸至生产,将由程序员这个遥远的祖宗所繁衍的所有子孙给联合在一起。
    1. 提高客户满意度
    2. 提高产品质量
    3. 提高员工的生产力和效率









    展开全文
  • 程序开发中遇到的问题—汇总

    万次阅读 多人点赞 2019-11-15 15:51:16
    程序面试题 1.bindtap和catchtap的区别是什么? bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡 2.Js数组转成换字符串,强制转换成整数及转换成浮点数的函数分别是什么? js...

     

    小程序面试题

    1. bindtap和catchtap的区别是什么?

    bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡

    2. Js数组转成换字符串,强制转换成整数及转换成浮点数的函数分别是什么?

    js提供了parseInt()和parseFloat()两个转换函数。前者把值转换成整数,后者把值转换成浮点数。只有对String类型调用这些方法,这两个函数才能正确运行;对其他类型返回的都是NaN(Not a Number)。

    1. 转换函数:

    在 判断字符串是否是数字值前,parseInt()和parseFloat()都会仔细分析该字符串。parseInt()方法首先查看位置0处的 字符,判断它是否是个有效数字;如果不是,该方法将返回NaN,不再继续执行其他操作。但如果该字符是有效数字,该方法将查看位置1处的字符,进行同样的 测试。这一过程将持续到发现非有效数字的字符为止,此时parseInt()将把该字符之前的字符串转换成数字。

    parseInt("1234blue"); //returns 1234 
    parseInt("0xA"); //returns 10 
    parseInt("22.5"); //returns 22 
    parseInt("blue"); //returns NaN

    2. 强制类型转换

    还可使用强制类型转换(type casting)处理转换值的类型。使用强制类型转换可以访问特定的值,即使它是另一种类型的。
    ECMAScript中可用的3种强制类型转换如下: 
    Boolean(value)——把给定的值转换成Boolean型; 
    Number(value)——把给定的值转换成数字(可以是整数或浮点数); 
    String(value)——把给定的值转换成字符串。

    3. 利用js变量弱类型转换

    举个小例子,一看,就会明白了。
    <script> 
    var str= '012.345 '; 
    var x = str-0; 
    x = x*1;
    </script>

    上例利用了js的弱类型的特点,只进行了算术运算,实现了字符串到数字的类型转换,不过这个方法还是不推荐的。

     

    3. 简单描述下微信小程序的相关文件类型

    小程序:pages ——index:index.js(页面逻辑) /index.wxml (页面结构)/index.wxss (页面样式表) / index.json (页面配置)

    App.js   小程序逻辑

    App.json  小程序公共设置

    App.wxss   小程序公共样式表

    4. 小程序有哪些参数传值的方法?

    1、设置id的方法标识跳转后传递的参数值;

    2、通过使用data - xxxx 的方法来标识要传递的值

    微信小程序设置id的方法标识来传值

    在要跳转的item处,设置一个id并给当前的id赋值上对应的key值,比如一部电影的id(后面带着id去下一个页面查询,详细信息)如:

    后我们在js的bindtap的响应事件中获取,并传递到下一个界面中;

    获取到id传的值

    通过e.currentTarget.id;获取设置的id值,并通过设置全局对象的方式来传递数值,

    获取全局对象 var app=getApp(); //设置全局的请求访问传递的参数 app.requestDetailid=id;

    提示:其实我们也可以在,wxml中查看到我们设置的每一个item的id值

    通过使用data - xxxx 的方法标识来传值

    通过使用data - xxxx 的方法标识来传值,xxxx可以自定义取名 比如data-key等等都可以。

    如何获取data-xxxx传递的值?

    在js的bindtap的响应事件中:

    通过数据解析一层层找到数据,var id=e.target.dataset.id(根据你的data-id的取名)

    微信小程序如何跨页面获取值?

    依据上面的方式设置要传递的值,页面跳转后,我们就需要在下一个页面拿到传递的数据(这个数据在传递前,就已经被设置成全局变量

    在跳转后的js页面,接收传递过来的数据detail.js

    同样通过全局额方式取值出来,(即和app.js中取某个变量的值是一样的)

    var movieid=getApp().MovieDetailid;
    console.log(movieid);

    5. 简述下wx.navigateTo(), wx.redirectTo(), wx.switchTab(), wx.navigateBack(), wx.reLaunch()的区别?

    微信小程序 跳转页面

    小程序页面有2种跳转,可以在wxml页面或者js中:

    1,在wxml页面中:

    <navigator url="../index/index">跳转到新页面</navigator>

    <navigator url="../index/index" open-type="redirect">在当前页打开</navigator>

    <navigator url="../index/index" open-type="switchTab">切换到首页Tab</navigator>

     

    2,在js页面中:

    【注意】此处注意两个关键词 “应用内的页面” 和 “tabBar页面”。  app.json文件中tabBar中注册过的tab页,即为“tabBar页面”,非tabBar中注册占用的页面即为“应用内的页面” 。 如下图:home页面为“应用内的页面”,index和logs页面则为 “tabBar页面”。

     

    3,如果上述跳转遇到跳转失败或无效的问题,请访问下面链接:

    wx.navigateTo/wx.redirectTo 无效

    6. 如果需要用户授权,用户选择拒绝授权,此时应该如何处理?

    在微信小程序开发时,当我们调用API  wx.getUserInfo(OBJECT) 时,需要用户授权。但如果用户拒绝授权,我们如何兼容用户拒绝授权状态,拥有更好的用户体验呢?

    先看看这个接口的官方文档:

    wx.getUserInfo(OBJECT)

    获取用户信息,需要先调用 wx.login 接口。

    OBJECT参数说明:

    参数名

    类型

    必填

    说明

    withCredentials

    Boolean

    是否带上登录态信息

    success

    Function

    接口调用成功的回调函数

    fail

    Function

    接口调用失败的回调函数

    complete

    Function

    接口调用结束的回调函数(调用成功、失败都会执行)

    1. tipwx.getUserInfo 接口需要用户授权,请兼容用户拒绝授权的场景。

    我们就是要在用户点击拒绝的时候,弹出提示框,提示用户以提升用户体验。像下面这样的。

    用具体代码实现就是,将弹窗写在 wx.getUserInfo 的fail回调函数中,像下面这样:

    wx.getUserInfo({

    success: function (resuser) {

    console.log(success)

    },

    fail: function () {// 调用微信弹窗接口

    wx.showModal({

    title: '警告',

    content: '您点击了拒绝授权,将无法正常使用******的功能体验。请10分钟后再次点击授权,或者删除小程序重新进入。',

    success: function (res) {

    if (res.confirm) {

    console.log('用户点击确定')

    }

    }

    })

    }

    })

    这样用户就获得了提示信息,但此时,用户还是停留在页面的,如果某些展示信息,还是给要给用户展示的,只是在进行某些操作的时候要对授权进行验证的话,那就得继续修改我们的代码,保存用户的登录态,在其他地方做验证使用。

    第一种思路:

    保存登录态这里是这样的,将用户的登录信息传给后台,后台保存用户信息,同时用 open_id 在后台换取一个SessionId  用换取的这个SessionId 存在缓存,做为登录态验证。

    wx.getUserInfo({

    success: function (resuser) {

    let userInfo = resuser.userInfo

    that.healthApi.login(code, userInfo).then(logindata => {   // 这里将微信的请求封装成Promiese 风格

    if (logindata.code === 0) {

    var sessionId = logindata.data// 调用微信wechat.setStorage将换回来的 SessionId 存在本地缓存

    that.wechat.setStorage('sessionId', sessionId).then(() => {

    that.globalData.userInfo = userInfo

    typeof cb == "function" && cb(that.globalData.userInfo)

    })

    }

    })

    },

    fail: function () {

    wx.showModal({

    title: '警告',

    content: '您点击了拒绝授权,将无法正常使用*****的功能体验。请10分钟后再次点击授权,或者删除小程序重新进入。',

    success: function (res) {

    if (res.confirm) {

    console.log('用户点击确定')

    }

    }

    })

    }

    })

    这样我们将登录态保存在了 SessionId 中,在每次登录的时候我们只需要再调用一个 检查 SessionId的接口就行,检查不通过再调微信登录接口。此处不做延伸了。

    第二种思路:

    在3.29微信小程序更新的版本中,加入了这样一条属性

    withCredentials 字段基础库版本 1.1.0 开始支持,低版本需做兼容处理

    这个字段的意思就是调用 wx.getUserInfo(OBJECT) 是否带上 登录态  的信息。

    官方文档是这样解释的:

    withCredentials 字段基础库版本 1.1.0 开始支持,低版本需做兼容处理

    注:当 withCredentials 为 true 时,要求此前有调用过 wx.login 且登录态尚未过期,此时返回的数据会包含 encryptedData, iv 等敏感信息;当 withCredentials 为 false 时,不要求有登录态,返回的数据不包含 encryptedData, iv 等敏感信息。

    success返回参数说明:

    参数

    类型

    说明

    userInfo

    OBJECT

    用户信息对象,不包含 openid 等敏感信息

    rawData

    String

    不包括敏感信息的原始数据字符串,用于计算签名。

    signature

    String

    使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息。

    encryptedData

    String

    包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法

    iv

    String

    加密算法的初始向量,详细见加密数据解密算法

    注:需要兼容微信低版本,向后兼容

    那么利用这个接口,我们可以直接拿到 登录状态,在其他需要验证登录的地方进行提示,而在不需要授权的地方还可以让用户浏览小程序。

    回到前面的问题,在用户点击拒绝授权后,在某些操作时需要验证用户是否授权过,弹出交互信息,那么就利用上面的 SessionId或者 withCredentials 登录态进行下面的操作:

    applyIn: function applyIn() {

    if (wx.getStorageSync('sessionId')) {  // 根据储存的sessionId 进行验证

    wx.navigateTo({

    url: 'familyDoctorApply/familyDoctorApply?Oid=' + this.data.params.Oid + '&title=' + this.data.params.title + '&serviceCity=' + this.data.array[this.data.index].name + '&productPrice=' + this.data.product.productPrice

    });

    } else {

    wx.showModal({

    title: '警告',

    content: '您点击了拒绝授权,无法使用此功能。',

    success: function (res) {

    if (res.confirm) {

    console.log('用户点击确定')

    }

    }

    })

    }

    效果像这样:

    这样一个简单完整的登录及授权,登录态保存等前端微信小程序解决方案就完成了,还可以继续扩展到登录有效期,退出登录,用户权限等跟多扩展的地方。

    7. 你平时封装可以复用的方法吗?你会把可以复用的方法写在哪个文件里?

    其实可以模拟一些框架的,比如bootsrap,写个demo出来,抽出css和js,js最好抽象成对象(构造函数)或者是带参数的方法,然后你只要声明对像,或者参数指定某个class或id,就可以了

    写在html文件里有什么优点吗?
    独立出来会有什么问题吗?尤其是载入页面的时候,应该会多发很多http请求吧,会不会造成加载变慢?

    8. 分析下小程序的优劣势?

    小程序是在微信生态发展过程中新出现的一种应用形态,小程序的小,从某种程度上已经说明了它的体量不会很大,但是可以实现一些功能相对简单、交互相对简单的服务需求,同时解决了App长期以来多平台适配、多应用市场分发、开发成本居高不下等诸多方面的问题。所以小程序【密件】依靠微信平台和自身“阅后即焚”的功能,获得众多年轻人的好评

    优势:

    1)容易上手,只要之前有HTML+CSS+JS基础知识,写小程序基本上没有大问题;当然如果了解ES6+CSS3则完全可以编写出即精简又动感的小程序;

    2)基本上不需要考虑兼容性问题,只要微信可以正常运行的机器,就可以运行小程序;

    3)基本组件库已经比较齐全:Toast,Loading框,Picker,定位及地图,Image,Input,Checkbox,Text,TextArea,ScrollView等常用的组件都有,而且使用也挺简单、方便;

    4)发布、审核高效,基本上上午发布审核,下午就审核通过,升级简单,而且支持灰度发布;

    5 ) 微信官方提供使用人数、频率等数据统计,小程序js脚本执行错误日志;

    6)开发文档比较完善,开发社区比较活跃;

    7)最近刚开放的牛x功能,新增webview组件,可以展示网页啦,这个比较爽;

    8)支持插件式开发,一些基本功能可以开发成插件,供多个小程序调用;

    劣势:

    1)后台调试麻烦,因为API接口必须https请求,且公网地址,也就是说后台代码必须发布到远程服务器上;当然我们可以修改host进行dns映射把远程服务器转到本地,或者开启tomcat远程调试;不管怎么说终归调试比较麻烦。

    2)前台测试有诸多坑,最头疼莫过于模拟器与真机显示不一致(之前碰到一个案例,后续单独讲解)

    3)真机测试,个别功能安卓和苹果表现迥异,我们的小程序里有很多页面有定位功能,模拟器和iphone定位瞬间完成,然而安卓手机就蛋疼了,老显示“定位中...”要很久才能定位好。后来没办法只能优化,减少定位次数。

    4)native组件,展示很不好,比如textarea,不能在滚动页面出现,而且至于顶层,经常其它组件会被它遮挡,点击其它组件时,就进入textarea输入框;画布组件也是如此;

    5)页面跳转深度不能超过5个页面,这个比较麻烦,有些复杂的页面跳转没法实现,不过太复杂的话也有悖小程序简单易用的原则啦;

    6)小程序升级问题,官方文档说会自动更新,实际情况往往是要先把原来的小程序删除掉,重新搜索添加,才能加载最新版本;

    7)页面渲染稳定性有待提高,已经好几次出现部分用户的页面显示异常,整个页面被放大了好几倍,先删除原来小程序再添加回来,如此重复好几次,才能显示正常;

    8)js引用只能使用绝对路径,很蛋疼;基于安全性及MINA框架实现原理,小程序中对js使用做了很多限制,不能使用:new Function,eval,Generator,不能操作cookie,不能操作DOM;

    9)开发工具bug比较多且效率比较低,三天两头升级,解决老问题的同时又出现问题;文件查找、资源定位、代码编辑较eclipse有一定差距。经常出现把a.js当做b.js来修改

    9. 设置值到页面暂存区(即data)里面的方法有几种?分别是什么?有什么区别?

    1. 使用QueryString变量
        QueryString是一种非常简单的传值方式,他可以将传送的值显示在浏览器的地址栏中。如果是传递一个或多个安全性要求不高或是结构简单的数值时,可以使用这个方法。但是对于传递数组或对象的话,就不能用这个方法了。下面是一个例子:
    a.aspx的C#代码
    private void Button1_Click(object sender, System.EventArgs e)
    {
     string s_url;
     s_url = "b.aspx?name=" + Label1.Text;
     Response.Redirect(s_url);
    }

    b.aspx中C#代码
    private void Page_Load(object sender, EventArgs e)
    {
     Label2.Text = Request.QueryString["name"];
    }

      2. 使用Application 对象变量
        Application对象的作用范围是整个全局,也就是说对所有用户都有效。其常用的方法用Lock和UnLock。
    a.aspx的C#代码
    private void Button1_Click(object sender, System.EventArgs e)
    {
     Application["name"] = Label1.Text;
     Server.Transfer("b.aspx");
    }

    b.aspx中C#代码
    private void Page_Load(object sender, EventArgs e)
    {
     string name;
     Application.Lock();
     name = Application["name"].ToString();
     Application.UnLock();
    }

      3. 使用Session变量
        想必这个肯定是大家使用中最常见的用法了,其操作与Application类似,作用于用户个人,所以,过量的存储会导致服务器内存资源的耗尽。
    a.aspx的C#代码
    private void Button1_Click(object sender, System.EventArgs e)
    {
     Session["name"] = Label.Text;
    }

    b.aspx中C#代码
    private void Page_Load(object sender, EventArgs e)
    {
     string name;
     name = Session["name"].ToString();
    }

      4. 使用Cookie对象变量
        这个也是大家常使用的方法,与Session一样,其是什对每一个用户而言的,但是有个本质的区别,即Cookie是存放在客户端的,而session是存放在服务器端的。而且Cookie的使用要配合ASP.NET内置对象Request来使用。

    a.aspx的C#代码
    private void Button1_Click(object sender, System.EventArgs e)
    {
     HttpCookie cookie_name = new HttpCookie("name");
     cookie_name.Value = Label1.Text;
     Reponse.AppendCookie(cookie_name);
     Server.Transfer("b.aspx");
    }

    b.aspx中C#代码
    private void Page_Load(object sender, EventArgs e)
    {
     string name;
     name = Request.Cookie["name"].Value.ToString();
    }

      5. 使用Server.Transfer方法
        这个才可以说是面象对象开发所使用的方法,其使用Server.Transfer方法把流程从当前页面引导到另一个页面中,新的页面使用前一个页面的应答流,所以这个方法是完全面象对象的,简洁有效。
    a.aspx的C#代码
    public string Name
    {
     get{ return Label1.Text;}
    }
    private void Button1_Click(object sender, System.EventArgs e)
    {
     Server.Transfer("b.aspx");
    }

    b.aspx中C#代码
    private void Page_Load(object sender, EventArgs e)
    {
     a newWeb; //实例a窗体
     newWeb = (source)Context.Handler;
     string name;
     name = newWeb.Name;
    }

     

    微信小程序--data的赋值与取值

    通过小程序官方文档可知:

    Page() 函数用来注册一个页面。接受一个 object 参数,其指定页面的初始数据、生命周期函数、事件处理函数等。其中的参数data用来设置初始数据,WXML 中的动态数据均来自对应 Page 的 data。

    所以如果页面需要显示动态数据必须要把数据更新到data中对应的变量中。

    · 页面js文件中这么写:

    Page({

      data: {

        message: 'Hello MINA!'

      }

    })

    · wxml中这么写:

    <view> {{ message }} </view>

    · 如果该数据在操作过程中发生变化,需要将新数据重新绑定到该变量中,写法如下:

    function setData(){

        var that = this;

        that.setData({

          message: '新消息'

        })

    }

    · 如果想在js文件中使用data中的数据写法如下:

    function getData(){

        var that = this;

        console.log(that.data.message)

    }

     

    10. 如何检测用户的微信版本是否支持某项功能?

    第一期开放的接口,不是不能使用,而是无需检测,全部都是支持的。
    只有后面最新开放的一些接口,才需要检测是否支持。
    目前开放的所有接口:
    onMenuShareTimeline
    onMenuShareAppMessage
    onMenuShareQQ
    onMenuShareWeibo
    onMenuShareQZone
    startRecord
    stopRecord
    onVoiceRecordEnd
    playVoice
    pauseVoice
    stopVoice
    onVoicePlayEnd
    uploadVoice
    downloadVoice
    chooseImage
    previewImage
    uploadImage
    downloadImage
    translateVoice
    getNetworkType
    openLocation
    getLocation
    hideOptionMenu
    showOptionMenu
    hideMenuItems
    showMenuItems
    hideAllNonBaseMenuItem
    showAllNonBaseMenuItem
    closeWindow
    scanQRCode
    chooseWXPay
    openProductSpecificView
    addCard
    chooseCard
    openCard

     

    11. 如何分包加载?分包加载的优势在哪?

    分包加载的介绍
          大部分小程序都会由某几个功能组成,通常这几个功能之间是独立的,但会依赖一些公共的逻辑,并且这些功能通常会对应某几个独立的页面。那么小程序代码的打包,大可不必一定要打成一个,可以按照功能的划分,拆分成几个分包,当需要用到某个功能时,才加载这个功能对应的分包。
    对于用户来说,小程序加载流程变成了:
    1.首次启动时,先下载小程序主包,显示主包内的页面;
    2.如果用户进入了某个分包的页面,再下载这个对应分包,下载完毕后,显示分包的页面。
    采用分包加载,对开发者而言,能使小程序有更大的代码体积,承载更多的功能与服务;而对用户而言,可以更快地打开小程序,同时在不影响启动速度前提下使用更多功能。
    分包的划分
    在配置前首先需要开发者规划下各个分包需要容纳的内容,我们建议开发者按照功能划分的的原则,将同一个功能下的页面和逻辑放置于同一个目录下,对于一些跨功能之间公共逻辑,将其放置于主包下,这样可以确保在分包引用这部分功能时,这部分的逻辑一定存在。
    在分包划分时,应该注意以下事项:
    1.避免分包与分包之间引用上的耦合。因为分包的加载是由用户操作触发的,并不能确保某分包加载时,另外一个分包就一定存在,这个时候可能会导致 JS 逻辑异常的情况,例如报「"xxx.js" is not defined」这样的错误;
    2.一些公共用到的自定义组件,需要放在主包内。
    分包的配置
          当理清了分包的划分后,就可以进行分包的配置了,这一步并不复杂。

          假设支持分包的小程序目录结构如下:

     

         开发者通过在 app.json subPackages 字段声明项目分包结构:

    分包加载的低版本兼容问题
       微信 6.6.0 版本开始支持分包加载,而对于低于这个版本的客户端,我们做了兼容处理,开发者不需要对老版本微信客户端做兼容。对于老版本的客户端,编译后台会将所有的分包打包成一个整包,老版本的客户端依然按照整包的方式进行加载。
    所以在老版本的微信客户端下,是依然采取整包加载的方式加载的,建议开发者尽量控制代码包的大小。
    目前小程序分包大小的限制:
        整个小程序所有分包大小不超过 4M
        单个分包/主包大小不能超过 2M
       随着时间推移,老版本覆盖率降低,我们会考虑进一步扩大代码包的大小。

     

    12. 在你开发小程序的过程中遇到过什么坑? 你是怎么解决的?

    1.我们使用app.json文件来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 的时候在pages中写注释的时候回报错。 
    例如:

    {

      "pages":[

          //这是首页面

        "pages/welcome/welcome"

      ]}

    此时就会报错 


    2.在json文件中没有写内容的时候也要加一对大括号{ },不然的话也会报错 
     
    3. ①在开发微信小程序的时候,我们使用app.json文件来对微信小程序进行全局配置,决定页面文件的路径,窗口表现,设置网络超时时间,设置多Tab等。 
    以下是一个包含了所有配置选项的简单配置,app.json :

    {

      //设置页面路径

      "pages": [

        "pages/index/index",

        "pages/logs/index"

      ],

      //设置默认页面的窗口表现

      "window": {

        "navigationBarTitleText": "Demo"

      },

      //设置底部 tab 的表现

      "tabBar": {

        "list": [{

          "pagePath": "pages/index/index",

          "text": "首页"

        }, {

          "pagePath": "pages/logs/logs",

          "text": "日志"

        }]

      },

      //设置网络超时时间

      "networkTimeout": {

        "request": 10000,

        "downloadFile": 10000

      },

      //设置是否开启 debug 模式

      "debug": true

    }

    ②但是在对页面json文件进行配置的时候只可以配置设置默认页面的窗口表现(即只能对window进行配置),但是在此时可以直接省略window,如果加window则没有效果,也不会报错。 
    以下是一个包含了window配置选项的简单配置,post.json :

    注意:这是错误的写法

    {

      "window":{

        "navigationBarBackgroundColor": "#ffffff",

        "navigationBarTextStyle": "black",

        "navigationBarTitleText": "微信接口功能演示",

        "backgroundColor": "#eeeeee",

        "backgroundTextStyle": "light"

      }}

    注意:正确的写法

    {

        "navigationBarBackgroundColor": "#ffffff",

        "navigationBarTextStyle": "black",

        "navigationBarTitleText": "微信接口功能演示",

        "backgroundColor": "#eeeeee",

        "backgroundTextStyle": "light"}

    4.此前一直没有注意vertical-align: middle和height:40rpx;line-height:40rpx进行设置垂直剧中的区别,这次主要说一下vertical-align: middle 
    代码如下:

    <view class="post-author-date">

        <image class="post-author" src="../../images/avatar/1.png">

        </image>

        <text class="post-date">Nov 15 2016</text>

    </view>

     

    .post-author{

        width: 60rpx;

        height: 60rpx;

        vertical-align: middle;

    }

    .post-date{

        margin-top: 5rpx;

        vertical-align: middle;

        /*height: 40rpx;

        line-height: 40rpx;*/

    }

    总结: 
    ①vertical-align: middle;把此元素放在父元素的中部 
    ②当一个父元素里面有多个子元素,需要把几个子元素水平对齐,并且每个子元素都垂直剧中的时候,对每一个子元素进行设置 vertical-align: middle 
    ③height: 40rpx; line-height: 40rpx;可以对文本进行垂直居中

     

    最后为了方便大家的沟通与交流请加QQ群: 625787746

    展开全文
  • 10分钟入门 - 微信小程序开发

    万次阅读 多人点赞 2019-05-29 13:12:55
    注册微信小程序 如果你还没有微信公众平台的账号,请先进入微信公众平台首页,点击 “立即注册” 按钮进行注册。注册的账号类型可以是订阅号、服务号、小程序以及企业微信,我们选择 “小程序” 即可。 接着填写...
  • 程序开发-启动页和首页

    万次阅读 2018-03-05 15:00:25
    微信小程序 配置启动页 在app.json文件中配置,该文件还可以配置首页进入的底部导航栏 app.js 是整个项目的全部js 优先加载app.js中的事件 app.wxss 也是全局的 如果要引入其他css文件 import 改文件的路径和全名...
  • 微信小程序开发需要什么技术

    万次阅读 2019-09-16 11:49:50
    那么微信小程序开发制件需要掌握哪些语言?  第一、微信小程序wxml  有过编程基础的工程师,在接触到wxml之后你才会发现,其实这个语言的编程理念和html网页的编程技术是类似的,当你研究一点时间后就...
  • 一个完整的软件项目开发流程

    万次阅读 多人点赞 2017-11-23 11:44:04
    在我转产品之前,虽然我混迹IT行业,做过实施和售前,也跟研发打过交道,但我一直都不知道一个软件是怎么开发出来的。直面客户,扛着压力,在对程序一无所知的情况下,很容易产生一些想法:为什么产品的结果是这样?...
  • 微信小程序开发实战

    万人学习 2019-04-01 14:05:00
    本套课程使用了元认知教学法,直接实战式教学,摆脱学院派的理论式讲解,对于0基础的学员可以入门编写微信小程序,过程中指导如何学习使用文档查阅接口等,通过两个完整的实战小项目的实例,入手小程序开发
  • 微信小程序开发教程(第1篇)

    万人学习 2018-10-22 21:38:05
    “微信小程序开发教程​”以腾讯官方资料为主,系统讲解微信小程序开发的相关的知识点。 全套课程共3篇 微信小程序实战教程(第1篇)——讲解小程序基础知识点,重点讲解小程序开发工具,视图层(View)和逻辑层(App ...
  • 微信小程序全方位深度解析

    万人学习 2019-06-24 13:09:17
    微信小程序是微信在2016年9月15日发布的一种新的应用形态,不需要下载安装即可使用的应用。本套视频教程将会带大家从基础环境搭建、配置、api的使用到开发出一个app的完整流程.
  • vsCode 开发微信小程序插件

    万次阅读 2018-02-07 08:21:47
    vsCode 开发微信小程序插件 问题描述 用微信开发者工具开发微信小程序不适应;没事,我们还有强大的 vsCode; 解决方案 用 vsCode 开发微信小程序可以配置以下插件,让开发更美好: 1. vscode weapp api ...
  • 微信小程序开发-新手环境配置

    万次阅读 2018-10-08 21:04:59
    首先我们新建小程序项目,填写申请的appID如果没有需要注册一个,微信为我们提供了一个云开发快速启动的模板,这里我们勾选进去看看云开发为我们提供的案例。     首次进入控制台会报cloud init error (云...
  • 然后上网百度了一波才...小程序开发官方文档提供了详细的教程,链接:小程序开发官方文档 二 小程序的限制 使用官方的开发工具 点击下载 配置合法的域名,需要https协议(测试的情况不需要) 三 配置本地开...
  • 征服微信小程序视频教程

    万人学习 2018-10-22 21:38:06
    征服微信小程序视频教程 微信小程序是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下...学员通过该视频课程,可以完全了解小程序开发方法,并可以独立开发完整的小程序
  • 小程序web-view使用方法是子恒老师《子恒说小程序开发》视频教程的第4部。详细讲解了小程序web-view组件的使用,内容包含web view打开网页,网页与小程序之间的跳转,在web view中实现微信支付等等。欢迎反馈,...
  • 微信小程序java开发流程分享

    万次阅读 2017-06-05 09:49:46
    前段时间,我接触了微信的开发小程序,在开发过程中,我不得不承认微信小程序开发的简单粗暴,不多说,直接hight。 微信小程序可以去公众平台下载。有64位和32位的。在这里我就不多哔哔了。 下载完微信小程序后,...
  • 几款微信小程序快速开发框架

    万次阅读 2018-12-02 14:58:14
    那么怎样才能快速开发一个小程序呢?下面小编为大家介绍几款小程序快速开发框架。WePY腾讯官方开源的小程序组件化开发框架,目前有1.4w+Star ,一直在更新着,社区活跃 ... 微信小程序是一种全新的连接用户与服务的...
  • 微信小程序开发实战入门,学习小程序云开发,摆脱后台,自己实现后台数据,从此就可以愉快的写小程序,自己实现小程序后台了。
  • 微信小程序开发实战第二季

    万人学习 2019-04-01 14:05:20
    本套课程仍然沿用了实战教学方式,以一个电影查询APP为实战案例,手把手从项目设计到开发,到封装重构的整套过程,让参与者掌握微信小程序开发的技巧和如何开发一个项目的整套流程。
1 2 3 4 5 ... 20
收藏数 2,985,141
精华内容 1,194,056
关键字:

程序开发