日期: 2022-09-20 15:23:24 浏览数:4

上往建站提供服务器空间服务商,百度快照排名,网站托管,百度推广运营,致力于设计外包服务与源代码定制开发,360推广,搜狗推广,增加网站的能见度及访问量提升网络营销的效果,主营:网站公司,百度推广公司电话,官网搭建服务,网站服务企业排名,服务器空间,英文域名等业务,专业团队服务,效果好。
启东网站建设【启东网络公司】启东做网站、启东微信公众号开发、启东网站设计、启东小程序制作
启东市,江苏省直辖,南通市代管,位于江苏省东南端,长江入海口北岸,是江苏省日出最早的地方。 [1] 户籍总人口110.35万,常住人口94.95万(2019年)。 [2] 截至2020年6月,启东市下辖9个镇。 [3]
后周显德五年(958年),置海门县于东布洲,隶于通州,海门县域包括今启东中部、北部地区。民国十七年(1928年),于崇明外沙设启东县。1989年,撤销启东县,设立县级启东市。 [14] [56]
启东是全国对外开放口岸 [4] 、中国建筑之乡 [5] 、国家卫生城市 [6] 、国家园林城市 [7] 、全国文明城市 [8] 、国家级生态示范区 [9] 、节水型社会建设达标县 [10] 、紧密型县域医共体建设试点县 [11] 、革命文物保护利用片区分县 [12] ,海洋经济之乡、电动工具之乡、建筑之乡、教育之乡、版画之乡。 [1]
2019年,启东市地区生产总值1157.55亿元,第一产业增加值79.64亿元,第二产业增加值581.29亿元,第三产业增加值496.62亿元。三次产业比为6.9:50.2:42.9。人均地区生产总值121879元。
复杂参数的传递
敏锐的读者会发现,上面有一个$query查询对象,这就是我们即将谈到的复杂参数的传递。
$query是查询对象PhalApi_ModelQuery的实例。我们强烈建议此类实例应当被作为值对象对待。虽然我们出于便利将此类对象设计成了结构化的使用。但你可以轻松通过new PhalApi_ModelQuery($query->toArray());来拷贝一个新的查询对象。
此查询对象,目前包括了四个成员变量:是否读缓存、是否写缓存、主键id、时间戳。很多时候,这四个基本的变量是满足不了各项目的实际需求的,因此你可以定义你的查询子类, 以支持丰富的数据获取。如调用优酷平台接口获取用户最近上传发布的视频时,需要用户昵称、获取的数量、排序种类等。
在完成了上面的工作后,让我们看下最终呈现的效果:
// 版本4:缓存 + 代理$query = new PhalApi_ModelQuery();$query->id = $userId;$modelProxy = new ModelProxy_UserBaseInfo();$rs = $modelProxy->getData($query);复制代码
在领域层中,我们切换到了Model代理获取数据,而不再是原来的Model直接获取。其中新增的是代理具体类 ModelProxy_UserBaseInfo,和可选的查询类。
至此,我们很好地在源数据的获取基础上,统一结合缓存策略。你会发现: 缓存节点可变、具体的源数据可变、复杂的查询亦可变 。

图2-4 代理模式下的UML静态结构
将此静态结构简化一下,可得到:

图2-5 简化后代理模式下的UML静态结构
这样的设计是合理的,因为缓存节点我们希望能在项目内共享,而不管是哪块的业务数据;对于具体的源数据获取明显也是不尽相同,所以也需要各自实现,同时对于同一类业务数据(如用户基本信息)则使用一样的缓存有效时间和指定格式的缓存key(通常结合不同的id组成唯一key);最后在前面的缓存共享和同类数据的基础上,还需要支持不同数据的具体获取,因此需要查询对象。也就是说,你可以在不同的层级不同的范畴内进行自由的控制和定制。
如果退回到最初的版本,我们可以对比发现,Model_Proxy就是Domain和Model间的桥梁,即:中间层。因为每次直接通过Model获取源数据的成本较大,我们可以通过Model_Proxy模型代理来缓存获取的数据来减轻服务器的压力。
细粒度的划分,对于支撑复杂的领域业务有着非常重要的作用。一来是更清楚明了的层次结构划分,二来是可测试性。
正如前面提及到的,我们在预览、调试、单元测试或者后台计划任务时,不希望有缓存的干扰。在细粒度划分的基础上,可轻松用以下方法实现而不必担心会破坏代码的简洁性。
取消缓存的方法1:外部注入模拟缓存
在构造Model代理时,默认情况下使用了DI()->cache作为缓存,当需要进行单元测试时,我们可以两种途径在外部注入模拟的缓存而达到测试的目的:替换全局的DI()->cache,或单次构造注入。对于计划任务则可以在统一的后台任务启动文件将DI()->cache设置成空对象。
取消缓存的方法2:查询中的缓存控制
在项目层次,我们可以统一构造自己的查询基类,以实现对缓存的控制。
如:
<?phpclass Common_ModelQuery extends PhalApi_ModelQuery {
public function __construct($queryArr = array()) {
parent::__construct($queryArr);
if (DI()->debug) {
$this->readCache = FALSE;
$this->writeCache = FALSE;
}
}}复制代码这样便可以获得了接口预览和调试的能力。
最后,让我们继续来完成前面的商品快照信息获取的实现。为简单起见,假设我们的商品数据不存在数据库,而是固定编码在代码中,并其数据和实现如下:
//$ vim ./Shop/Model/Goods.php<?phpclass Model_Goods {
public function getSnapshot($goodsId) {
$allGoods = array(
1 => array(
'goods_id' => 1,
'goods_name' => 'iPhone 7 Plus',
'goods_price' => 6680,
'goods_image' => '/images/iphone_7_plus.jpg',
),
2 => array(
'goods_id' => 2,
'goods_name' => 'iPhone 6 Plus',
'goods_price' => 4588,
'goods_image' => '/images/iphone_6_plus.jpg',
),
);
return isset($allGoods[$goodsId]) ? $allGoods[$goodsId] : array();
}}复制代码这里硬编码了两个商品:iPhone 7 Plus和iPhone 6 Plus。然后执行一下最初的单元测试,发现已经可以通过测试了。
$ phpunit ./Api/Goods_Test.php ... ...OK (2 tests, 5 assertions)复制代码
是不是发现接口服务开发,其实也很有趣?
传统的接口开发,由于没有很好的分层结构,而且热衷于在一个文件里面完成绝大部分事情,最终导致了臃肿漫长的代码,也就是通常所说的意大利面条式的代码。
在PhalApi中,我们针对接口领域开发,提供了新的分层思想:Api-Domain-Model模式。即便这样,如果项目在实际开发中,仍然使用原来的做法,纵使再好的接口开发框架,也还是会退化到原来的局面。
为了能让大家更为明确Api接口层的职责所在,我们建议:
Api接口服务层应该做:
应该:对用户登录态进行必要的检测
应该:控制业务场景的主流程,创建领域业务实例,并进行调用
应该:进行必要的日记纪录
应该:返回接口结果
应该:调度领域业务层
Api接口服务层不应该做:
不应该:进行业务规则的处理或者计算
不应该:关心数据是否使用缓存,或进行缓存相关的直接操作
不应该:直接操作数据库
不应该:将多个接口合并在一起
Domain领域业务层应该做:
应该:体现特定领域的业务规则
应该:对数据进行逻辑上的处理
应该:调度数据模型层或其他领域业务层
Domain领域业务层不应该做:
不应该:直接实现数据的操作,如添加并实现缓存机制
Model数据模型层应该:
应该:进行数据库的操作
应该:实现缓存机制
在明确了上面应该做的和不应该做的,并且也完成了接口的定义,还有验收测序驱动开发的场景准备后,相信这时,即使是新手也可以编写出高质量的接口代码。因为他会受到约束,他知道他需要做什么,主要他按照限定的开发流程和约定稍加努力即可。

启东网站建设【启东网络公司】启东做网站、启东微信公众号开发、启东网站设计、启东小程序制作
上往建站提供搭建网站,域名注册,官网备案服务,网店详情页设计,企业网店,专业网络店铺管理运营全托管公司咨询电话,服务器空间,微信公众号托管,网页美工排版,致力于域名申请,竞价托管,软文推广,全网营销,提供标准级专业技术保障,了却后顾之忧,主营:虚拟主机,网站推广,百度竞价托管,网站建设,上网建站推广服务,网络公司有哪些等业务,专业团队服务,效果好。
服务热线:400-111-6878 手机微信同号:18118153152(各城市商务人员可上门服务)