发表日期: 2021-04-26 09:43:12 浏览次数:92
如皋申请400电话费用【如皋企业全国热线电话办理】如皋开通400电话电信价格、如皋微信公众号代运营外包托管、如皋网店编辑装修美工、如皋网站推广优化大概需要多少钱
如皋市,简称“如”或“皋”,江苏省辖县级市,由南通市代管,江苏省历史文化名城。地处长江三角洲北翼,位于南通、泰州、苏州三市交界处,南与张家港市隔江相望,北与海安市、东与如东县连接、东南与南通市通州区毗邻,西与泰兴市、西南与靖江市接壤。全市总面积1477平方公里(不含长江水面),长江水面99平方千米。如皋长江岸线全长48千米,可直接利用长江深水岸线18.6千米。
如皋市被国际自然医学会评为世界六大长寿乡之一。 [1] 如皋市户籍人口约142万。截至2021年1月1日,全市80周岁以上高龄老人68031人,90周岁以上高龄老人10150人,百岁老人达525位,其中105岁以上达16位。 [2]
2019年6月17日,如皋被中华人民共和国住房和城乡建设部选取作为开展规范城市户外广告设施管理工作试点城市。 [3] 2019年10月8日,被评为2019年度全国综合实力百强县市、2019年度全国绿色发展百强县市、2019年度全国新型城镇化质量百强县市、2019全国营商环境百强县。 [4-6] 2020年12月,社科院发布《全国县域经济综合竞争力100强》,如皋排名第31 [7] 。
我们在PhalApi中继续使用了Model层,受MVC模式的影响,大家都对Model层非常熟悉,但可能会在潜意识中存在误解。再强调一次,PhalApi为Model层赋予了新的诠释和活力,其数据来源不局限于数据库,可以是通过开放平台接口获取的数据,也可以是不落地直接存放于缓存的数据,还可以是存储在其他媒介的数据。
Model层主要是关注技术层面的实现细节,以及需要考虑系统性能和海量数据存储等。如果数据来源于数据库,我们则需要考虑到数据库服务器的感受,保证不会有过载的请求而导致它“罢工”。对此,我们可以结合缓存来进行性能优化。
如,一般地:
// 版本1:简单的获取$model = new Model_User();$rs = $model->getByUserId($userId);复制代码
这种是没有缓存的情况,当发现有性能问题并且需要通过添加缓存来解决时,可以这样调整:
// 版本2:使用缓存$key = 'userbaseinfo_' . $userId;$rs = DI()->cache->get($key);if ($rs === NULL) {
$rs = $model->getByUserId($userId);
DI()->cache->set($key, $rs, 600);}复制代码但不建议在领域Domain层中引入缓存,因为会导致混淆Domain层的关注点,并且不便进行测试。更好是将技术层面的缓存机制处理移至Model层,保持数据获取的透明性:
<?phpclass Model_User extends PhalApi_Model_NotORM {
public function getByUserIdWithCache($userId) {
$key = 'userbaseinfo_' . $userId;
$rs = DI()->cache->get($key);
if ($rs === NULL) {
$rs = $this->getByUserId($userId);
DI()->cache->set($key, $rs, 600);
}
return $rs;
}复制代码对应地,在Domain层的调用改为:
// 版本3:使用缓存 (缓存机制封装在Model层)$model = new Model_User();$rs = $model->getByUserIdWithCache($userId);复制代码
至此,Model层对于上层如Domain来说,负责获取源数据,而不管此数据来自于数据库,还是远程接口,抑或是缓存包装下的数据。这正是我们使用数组在Model层和Domain层通讯的原因,因为数组更加通用,不需要额外添加实体。但如果项目有需要,也可以添加DTO这样的层级。
纵使更富表现力的Model很好地封装了源数据的获取,但是仍然会遇到一些尴尬的问题。特别地,当我们大量地进行缓存读取判断时,会出现很多重复的代码,这样既不雅观也难以管理,甚至会出现一些简单的人为编写错误而导致的BUG。另外,当我们需要进行预览、调试或测试时,我们是不希望看到缓存的,即希望能够手工指定是否需要缓存。
这里再稍微简单回顾总结一下现在所面临的问题:我们希望通过缓存策略来优化Model层的源数据获取,特别当源数据获取的成本非常大时。但我们又希望我们可以轻易控制何时需要缓存,何时不需要,并且希望原有的代码能在OCP的原则下不需要修改,但又能很好地传递源数据获取的复杂参数。归纳一下,则可分为三点:缓存的控制、源数据的获取、复杂参数的传递。
缓存的控制
不管是单点缓存,还是多级缓存,都希望使用原有已经注册的cache组件服务。所以,应该使用委托。委托的另一个好处在于使用外部依赖注入可以获得更好的测试性。
源数据的获取
源数据的获取,作为源数据获取的主要过程和主要实现,需要进行缓存的控制(可细分为:是否允许读缓存、是否允许写缓存)、获取缓存的key值和有效时间,以及最终原始数据的获取。明显,这里应该使用模板方法,然后提供钩子函数给具体子类。
这里,我们提供了Model代理抽象类PhalApi_ModelProxy。之所以使用代理模式,是因为实际上并不一定会真正调用到最终源数据的获取,因为往往源数据的获取成本非常高,故而我们希望通过缓存来拦截数据的获取。
由于Model代理被上层的Domain领域层调用,但又依赖于下层Model层获得原始数据,所以处于Domain和Model之间。为了保持良好的项目代码层级,如果需要创建PhalApi_ModelProxy子类,建议新建一个ModelProxy目录。
如对用户基本信息的获取,我们添加了一个代理:
<?phpclass ModelProxy_UserBaseInfo extends PhalApi_ModelProxy {
protected function doGetData($query) {
$model = new Model_User();
return $model->getByUserId($query->id);
}
protected function getKey($query) {
return 'userbaseinfo_' . $query->id;
}
protected function getExpire($query) {
return 600;
}}复制代码其中,doGetData($query)方法由具体子类实现,委托给Model_User的实例进行源数据获取。另外,实现钩子函数以返回缓存唯一key,和缓存的有效时间。
这里只是作为简单的示例,更好的建议是应该将缓存的时间纳入配置中管理,如 配置四个缓存级别:低(5 min)、中(10 min)、高(30 min)、超(1 h) ,然后根据不同的业务数据使用不同的缓存级别。这样,即便于团队交流,也便于缓存时间的统一调整。

如皋申请400电话费用【如皋企业全国热线电话办理】如皋开通400电话电信价格、如皋微信公众号代运营外包托管、如皋网店编辑装修美工、如皋网站推广优化大概需要多少钱