产品设计与软件服务杂记

最近闲赋在家,在清明小长假开车长途跋涉3000多公里办完了家里的一件事情,这本身是一种锻炼,同时也让自己放松了一下。闲赋期间也与众多朋友进行沟通交流,同时也收到了一些电子产品的礼物,就对这些谈谈自己的看法。

沟通交流多涉及传统行业或正常业务想利用软件来拓展自己业务,跟随现在的热潮,这些沟通交流也多集中在电商方面,我对于电商是不懂的,没有这方面的从业经验。在沟通交流的过程中多数扮演倾听者的角色,倾听现有的业务如何开展电子商务的美好前景,如何大展宏图,趁着这波电商及移动电商热潮让公司的量级在提升一个台阶。另一种沟通交流涉及的是现有的业务希望能够使用一定的软件来辅助业务本身,期望用软件来提升服务质量,形成自己的独有竞争力。

沟通交流的后半阶段总会涉及到多少人多长时间能够完成这些想法,然后就有外包给团队完成这些的打算,给我的最直观的能够形容的就是这些想做的事情是一锤子的买卖,这也是我近两年碰到比较多的传统行业经营者比较普遍的想法。我对于此的一般建议是让其慎重考虑,主要集中在几点:

(1)这些预计投入建设的都是其核心业务,不在于做出来,而在于做出来后通过不断的运维,经历由营销指导系统建设到系统驱动营销;
(2)核心要做的事情和要形成独有竞争力的事情不宜外包,否则在很大程度上会陷于外包这个泥潭而很不好脱身;
(3)从长期来讲做这类的事情需要有自己的团队,而不是一锤子买卖,我要做这些,你做了这些就行了,这样做多半会夹生,最后不了了之,浪费资源不说,同时也不会有好的结果;
(4)应该有足够的耐心,当真的确定开始之后,这玩意在很长一段时间就是无底洞,看不到底,没有足够的耐心会让团队很茫然,在过程中就会分崩离析。

这些是跟我老本行相关的我的一些看法,我不懂电商,就是从系统建设方面的一些建议,更多的是给他们泼冷水,不是简单的找台服务器、架设电子商城系统或开发一个简单的软件从辅助业务开始形成独有竞争力,其实有时候看上去简单却不简单。

下面再说说朋友给的电子产品「收音机」,这东西是我有段时间问朋友索求的,最近一下子拿到了好几台,主要给母亲使用,这玩意在我的记忆中从来都没有非常火热过,从使用人群出发,记忆中最早家中会有大块头的收音机,仅仅留存在记忆中的这段时间会有「小喇叭什么什么的」,再往后就是在老人跟学生这个群体中使用,现在人们生活变好了,私家车多起来后,在开车中常会听听车载收音机,目前应该在老人跟司机群体中使用较多,至于年轻人可能就通过手机偶尔来听一听了。刨除车载收音机使用人群以外,可能老年人是一直在使用的一个群体而且是目前使用居多的人群。

最近拿到的几台收音机越发的精致跟小巧了,从使用者的特点来看,精致跟小巧是必要的,但是小巧的基础上应注使用人群的特点,比如现在的小按键、数字屏上小字体、小图标对于老年人来讲操作起来就有些不便了。功能操作的数字化这方面也需要一段时间来学习,当然这点我认为是值得的,都要与时俱进嘛,母亲最钟爱的还是「德生」老式收音机,是需要花一段时间来熟悉数字化带来的好处。

不管硬件产品的设计还是软件产品的设计,其受众特点都是需要在设计中考虑的重点之一,只有充分考虑了这些,最终的接口才会有良好的人际体验,就收音机这个电子产品,可能在不久的将来就会彻底消失,但电台会以另外一种方式传播。

「收音机的使用人群是不是我写的这样,下一回跟从事广播的朋友有待沟通确认!」

php学习练习(2)-微信版宝宝睡前故事

小的功能需求在生活的周围存在很多,这些功能需求的编程实现是学习的一种良好方式。对于给孩子读睡前故事是现阶段我这个家庭的需求,买了不少故事书,也有读,就想着将这些故事放到手机上也是一个不错的选择。

时下比较火热的「微信」是手机上呈现的一个不错的方式,于是着手规划这个小的功能需求,这个小的需求分为两部分,第一部分是服务器端对于故事的组织与管理;第二部分是服务器端与微信公众号之间的接口实现。

服务器端需要一个存储故事的数据库,用于存储故事数据,一组页面及其脚本来完成故事的管理,完成对应于数据库的ADU相关操作。剩下的就是与微信的接口部分,通过微信公众号的自定义菜单获取每日睡前故事,通过脚本依据当日信息组成微信公众号的图文信息,点击后展现故事。

最终的阅读操作如图所示「如果你也有这样的需求,可通过微信搜索smallsoftware关注即可使用,也可在微信中扫描本Blog右侧二维码直接关注」:

babystorys

微信接口这部分主要是从数据库中获得数据,然后组织成图文信息即可,根据微信自定义菜单的KEY完成组装即可。

$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
if(!empty($postStr)) {
  $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
  $fromUser = $postObj->FromUserName;
  //详细请参看微信公众帐号开发接口文档
  //...
  $fromMsgType = $postObj->MsgType;
  //...
  if($fromMsgType == "event") {
    $formEvent = $postObj->Event;
    if($formEvent == "CLICK") {
      $eventKey = $postObj->EventKey;
      if($eventKey == 'YOUR_KEY') {
        //取数据
        //组织图文信息数据
        //输出
      } else { //... }
    }
  }
//......

服务器端包含故事的添加、修改、删除、查看,用于后台对于故事的管理。使用了Bootstrap前端框架的部分内容,具体的结构如下。

babystory archite

数据库类基于PDO,故事类继承数据库类,完成故事的数据相关操作封装及故事的展现,admin类完成权限和管理的封装,前端页面通过init入口完成对于数据的管理工作,init入口部分完成数据的初始化工作与上下交互操作。

没有其他可供的选择,每天一篇睡前故事,对于选择性故事的定制阅读及过往的查询不支持,对于用户阅读这部分的统计也没有完成,可以说留下了不少的坑等着填。

至于微信自定义菜单,根据其接口文档中的说明,先要由appid和secret通过一个URL用Get方式获得AccessToken,然后将准备好的菜单和获得的AccessToken通过一个URL用POST的方式提交数据,从而创建自定义菜单。

<!--?php
  class WechatMenu {
    private $_appid = "";  //你的appid
    private $_secret = ""; //你的secret
    function __construct($menu) {
      //先获得AccessToken
      $result = $this--->getAccessToken();
      if(array_key_exists('errcode', $result)) {
       throw new Exception($result['errmsg'], 1);
      } else {
         $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" . $result['access_token'];
         $result = $this-&gt;Post($url, $menu);
         if($result['errcode'] == 0) {
           //ok
         } else {
           throw new Exception($result['errcode'], 1);
         }
      }
    }
    
    private function Post($url, $data) {
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
      $data = curl_exec($ch);
      curl_close($ch);
      return json_decode($data,true);
    }

    private function Get($url) {
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
      $data = curl_exec($ch);
      curl_close($ch);
      return json_decode($data,true);
    }

    private function getAccessToken() {
      $grant_type = "client_credential";
      $appid = $this-&gt;appid;
      $secret = $this-&gt;secret;
      $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type={$grant_type}&amp;appid={$appid}&amp;secret={$secret}";
      $result = $this-&gt;Get($url);
      return $result;
    }
  }
?&gt;

调用 (1) 生成json格式的菜单数据 (2)new WechatMenu($menu);

wechatmenu

-EOF-

一个游戏运营项目失败的思考

这是我对自己参与的一个项目失败的思考,有点马后炮的赶脚。仅仅代表个人的观点和看法,不一定正确,仅供记录我这个阶段的一些想法,积累下来以供将来重新的审视与提高。

先简要的介绍一下这个项目,这是一个网络游戏在海外运营的项目,促成这个项目的开始是出自同事以往行业内的从业经历,恰逢其会的是该同事具有前期能引流的人脉并且也愿意一番尝试,在技术上也具有在预期时间内完成基础平台建设的能力。在项目启动之初,可谓「天时、地利、人和」齐活了,一个比较完美的开始就这样诞生了,剩下的就是甩开膀子,在快速迭代试错中迈着小碎步向前奔跑,以成就一番事业。

「愿望总是美好的,现实总是残酷的」,我甚至不知道这个项目最终结束的具体时间,因为项目进行的中间我就已经离开这个游戏创业项目了,很短暂的开始,很短暂的结束,但当整个团队决定开始增加新方向的时候,这个项目终将结束在我看来也是必然的。

gameplatform

按照这个项目来说,项目的主体共有三方组成:游戏厂商、初始用户导入方、平台运营团队。三方各司其职,共同推进整个项目的发展。

(1)被选中且能够与我们开展合作的游戏厂商的主要工作是完成游戏的接入,游戏的升级维护及节日活动的推出与定制,另外就是三方的结算对账。
(2)初始用户导入方完成用户的引流工作,以及运营分成的财务结算对账,完成境外其他资源引流的合作洽谈,找出最佳的引流途径。
(3)平台运营团队就是我们了,主要负责运营平台的建设、游戏的筛选与签订合同、游戏接口与平台的接入、平台的充值及换算、后台数据分析与核对、游戏运营活动的策划与运营推广、游戏客服、「建立自己的用户资源」、与各方财务结算。

游戏厂商在整个进程中的配合是非常良好的,在发生问题的时候总是能及时得到反馈,在活动及游戏内资源的支持上也不遗余力,而且从洽谈的过程中,能明显的感觉到他们是乐意合作的。

初始用户的引流工作虽然是资源方乐意尝试的,但不是其主营,这点上可能力度有待进一步加强,这些可以通过沟通来解决,还有就是对于引流的效果应该由我们结合引流方式给予资源方一定的支持,当然这些是要依据一定的数据方式,比如在游戏中做一些有奖励的调查问卷来获得其大部分的来源途径,其实这些在资源方那边是可以统计出来的。

我主要负责技术这块,并且参与跟游戏厂商的洽谈接触,在初始系统基础上安排设计人员和开发人员进一步定制以后基本上满足开始的运营需求,整个平台就这样开始运营了。我一直认为在一件事开始之后,专注与围绕专注开展工作是一个前提,就这个平台开始运营之初,构成其未来的主要工作集中在两部分:「其一是运营推广,这是重中之重,其长期努力的方向是建立自己的用户资源;其二是围绕运营推广提供强劲持久的技术驱动力,持续发展运营平台及其周边增值服务,保证给不同类别的用户持续输出富有娱乐性的游戏」。

围绕这两部分开展工作就是基础,刚开始运营其实从数据上来看还是比较符合预期的,在差不多一个月单游戏单区的情况下,用户注册数、每日在线数、充值数、日注册及活跃增长数及用户留存率上来看还相对符合预期,下面是一个月的部分充值记录。

paysummary

有了一个好的开始,但随后突然就放下了,主要的工作没有行之有效的开展,或者说没有足够的努力。危机意识不强,对技术长期驱动力的价值也不太认可,加上团队成员的实际生活问题等诸多因素的影响下,又有了开展其他行业新业务想法。在这种情况下,我最终选择了离开,因为我没有更多的资金投入开展新的业务,同时我也不认为当时的团队与投入能够有精力同时开展两条线的业务。

至于说主要的工作没有行之有效的开展是我个人的观点,对于我这个初次涉足游戏行业的人来说,在开始到离开这段时间其实有不少的想法,比如说在通过资源方引流的原始用户基础上,通过怎样的策划与推广,带来新的朋友用户,能不能制订积分体系加物质激励来完成?能不能通过游戏虚拟物品激励来完成,平台自己是否增加用户推荐体系并给予满足条件的推荐用户以激励?围绕游戏如何建立社区论坛?能否增加周边商城拓展游戏增值服务?满足这些运营平台应怎样重新架构? 诸如此类的想法有不少,但是这些想法没有成文后与团队成员进行充分的沟通,虽然这些想法对于初涉游戏行业的我显得比较稚嫩,但至少也应该跟团队成员讨论一下,在讨论过后相信自己也能获得长足的提高,增加对这个行业的认知。

危机意识不强的很大一部分原因是被这开始的充值额冲昏了头脑,按照一款游戏一个区来计算,想来多款游戏多个区就能达到预期,从我后来离开后的间断性关注中,先后上线了新的两款游戏,并且增加了新开区,但是充值及用户增长却一度中断,中间我没有看到任何针对这些不好影响的调整。这段时间我的猜测是人力资源不能跟进以保证用户的使用引导及足够的支持工作,由于新开展的其他行业新项目占据太多的精力,导致迟迟没有建立初步的用户服务机制、用户引入机制、用户激励机制、用户参与机制等。且在整个行业的发展中,游戏的变化也是急剧的,缺少对端游、页游、手游这些不同类型游戏的持续性关注。

再往后就没有往后了,却留下了诸多的不良影响,影响之一是在合作过程中给其他两方留下了一定的印象;影响之二是给玩过一阵的玩家留下了一定的印象,进而导致资源方也给玩家留下了足够的印象;影响之三是给所有团队成员留下来一定的印象。那么收获呢?

对于我来说这个短暂的创业经历有几点收获:

(1)要一直专注,所有要做的事情都要围绕最初设定的目标来做,尝试能够尝试的一切方法只为向目标迈进或者由目标衍生的新目标,直至结束,在未终止前我们其实没有更多的精力同时专注两件事;
(2)要有危机感,要给自己设定尽量涵盖全范围的最差的情况,然后设法找到解决方式,时刻保持危机感能促使专注;
(3)运营是重中之重,运营始终需要强力的技术作为保障,从这个角度来讲,技术是运营的支撑,技术是驱动力,要尽量获得团队成员对技术的认可,运营平台系统的建设不是一锤子买卖,需要长时间的演变,从功能到架构;
(4)要设定退场时对各方影响的补偿机制,用户从开始使用提供服务的第一天就会投入情感,任何时候不要让用户失望,说不定结束前小小的沟通就能超出用户的预期;
(5)人在任何时候都是关键,保持足够的沟通能够增加互相的了解,比较理想的是在没明确结束前,大家都能全力的参与其中;
(6)多少人做多少事,我们往往太过相信自己能够做的更多,可往往我们并不能做更多的事情,我们往往过高估计自己。

php中的魔术方法

php中内置了不少被赋予魔术性质的「魔术方法」,魔术方法以双下划线开头「__」,在类中使用,在特定的条件下自动在程序中被调用,由于具有在特定条件下自动被调用的特性,使得编程过程得以简化。

在PHP中魔术方法有:__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), __autoload()

1. __construct() 和 __destruct()

__construct()和__destruct()分别称为构造函数与析构函数,在对象被创建和销毁的时候由系统自动调用,跟其他编程语言中构造函数与析构函数一样,也是在面向对象编程中使用最频繁的。

构造函数主要完成对象在创建时候的初始化工作,一般用于初始化对象的成员,在PHP中,子类使用父类的构造函数必须使用parent::__construct()显示调用,不支持隐式自动调用。

对应的析构函数是对象在被系统销毁时自动调用。包括对象被显式销毁或者该对象的所用引用都被删除。跟构造函数一样,子类析构函数使用父类析构函数同样使用parent::__destruct()显示调用。

construct

2. __call()和__callStatic()

当调用对象不可访问的方法或者没有的方法时自动调用__call()魔术方法。该魔术方法有两个参数,第一个是调用的方法名称,第二个参数是枚举数组参数列表。用静态方式调用不可访问的方法或者没有的方法时自动调用__callStatic()魔术方法。

测试后发现对于存在但不可访问的方法并不能通过__call来调用,调用顺序为,先在自己类中寻找方法,如没找到,向父类中寻找,如果在父类中找到则调用父类中方法,如果没有找到而本类中有__call方法则执行__call魔术方法。

call_01

该魔术方法另外一个比较重要的用途就是实现重载,在PHP手册中这两个魔术方法介绍的标题也是方法重载。

call_02

3. __get() 和 __set()

当读取不可访问或者未定义的属性时,访问__get()方法。当设置不可访问或者未定义的属性时,访问__set()方法。

4. __isset()和__unset()

当在一个未定义或者不可访问的属性中调用isset()函数时访问__isset()方法。当在一个未定义或者不可访问的属性中调用unset()函数时访问__unset()方法。

 5. __sleep()和__wakeup()

这两个魔术方法在进行序列化的时候使用,通过序列化可以将任何类型数据转化为字符串格式,我们可以通过序列化对象,将其转化为字符串格式保存起来。在进行序列化的时候,检查类中是否有__sleep()魔术方法,如果有就调用该方法。在进行反序列化的时候会检查类中是否有__wakeup()魔术方法,如果有就调用该方法。

通常在__sleep()方法中处理不需要序列化的部分内容或者做一些对象的清理工作,而在__wakeup()方法中进行一些初始化操作。这两个方法是配合序列化和反序列化使用的。

6. __toString()

将对象当初字符串在程序中使用时,会自动调用该方法,例如我们echo一个对象时将调用这个方法,如果不存在该方法,则出现错误。

7. __invoke()

当尝试以调用函数的方式调用一个对象时,__invoke 方法会被自动调用。

8. __set_state()

当调用var_export()导出类时,该方法被自动调用。

9. __clone()

复制对象时使用clone方法,在复制完成时,如果定义了__clone方法,则会自动被调用,可用于修改新复制对象的属性或进行初始化工作。

10. __autoload()

使用这个方法可以进行类的自动加载,比如我们可以在该方法中完成包含文件的自动加载。

autoload

怎么「写」产品在同类中具有的优势?

在交流中提及到一个经常碰到的问题,”同类的产品有很多,怎么写产品在同类中具有的优势?“。这样的场景经常会出现在工作当中的介绍产品的文档中,在这里往往都是在关注如何「写」,通常情况下都是赞誉自己的产品,贬低同类的产品,从而让自己的产品显得具有优势,达到往往并不能取得效果的结果。

在企业应用的系统中,这类的事情出现的很频繁,在以往的工作中频频碰到,而且也操刀写了不少如此这类的文档,如今想来,甚是惭愧。企业应用系统,尤其是管理类系统,多数以企业业务场景出发进行业务场景下的信息化工作,一般是对贯穿于企业业务流程及在流程中产生的数据进行管理,从而实行信息化管理。这样的系统从第一感官来看,往往都很相似,UI相似(框架),功能相似(业务),往往都是你家有的我家也有,如何「写」出产品比同类产品的优势就显得是重要的。刨除很特殊的关系这一层面的营销,现在我的看法可能会更多的受到互联网产品及移动产品的影响,不在于如何写,在于如何做。

最近几年互联网/移动互联网类的产品的变化是非常巨大的,可是看企业类的系统,最近这些年的变化却不甚明显,相当一部分都还停留在若干年前的状况,当然规模及功能上的变化是巨大的,看上去很复杂,功能聚合是越来越多,这些是看到的变化,看不到的是交互体验方面的变化。

从实际业务场景建立功能是第一步系统开发要做的,要切实的解决业务场景的需求,这是可以通过进入这个行业实际工作一阵子,或者寻求行业专家的支持,完成后,大部分系统都具有雷同的功能,毕竟都是解决同样业务的。

能够顺畅的完成业务场景的工作或许是大部分企信息化系统之间相互比拼的,随着时间的变化当功能越来越雷同和相似后,同时也有了初步的业务数据,这时候先行者就会抛出几个概念性的东西,凡是跟数据沾边的跨信息孤岛的其他范围就被纳入其中,然后做一些接口以便跟其他系统互通,这是第二步的工作。

随着接口的增多与各个系统之间的数据积累,基于数据的服务或许是第三步要做的工作,企业信息化系统这方面相对比较复杂,其复杂主要集中在各个系统数据接口的建立,然后是从整体上能够提供基于数据的分析、处理、归纳,从整体上提供服务,另外一部分是面对系统的升级带来的复杂性,这几方面共同作用下,让这些年来的企业信息化系统基本上停留在这个阶段,且存在不少实际上依旧互相并不互通的问题。

一般「写」产品优势就是从上面这三步出发,很多企业基本上没进入第二步就折戟沉沙,太过专注「写」,其实在「写」的同时,更应该关注做,做好每一步而不是「写」好每一步更能让企业持续的经营下去,而大部分企业,这里中小型企业居多更多的是关注写,不能沉下心来好好做,这样的企业不死谁死?所以还是在市场营销反馈良好的情况下,应该做好这些,从而自然写起来就有优势了。

同样的,这些年来企业信息化系统的交互体验同样不能获得重视,从交互性和体验性上来讲,往往开发这类系统的公司投入都相对较小,或者压根就不注意这些地方,这样的第一个要面对的就是在实施后的培训时间周期很长,而大多是基于操作层面的培训。最终使用用户使用体验比较差劲,相对比较生硬,亲和力比较低。持续的注重交互体验,让系统变得能够很大程度上提高效率应该是能让你的系统脱颖而出的很重要的优势,交互体验应该贯穿于整个企业信息化系统开发之中。或许也会是让你的企业信息化系统脱颖而出的开始。

前两天朋友在交流中问我“如何才能写出我现在的系统的优势?“,我给的建议是「根植于业务,向服务靠拢,产品体验贯彻整个过程」。做好这些就具有了水到渠成的优势,你的系统做到哪一步了?