·设为首页收藏本站📧邮箱修改🎁免费下载专区📒收藏夹👽聊天室📱AI智能体
返回列表 发布新帖

【开发指南】X3.5插件适配之LSP(Liskov 替代原则)

585 2
发表于 2021-4-13 18:16:51 | 查看全部 阅读模式

马上注册,免费下载更多dz插件网资源。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
x3.5新增了插件的审核要求:
自带表类必须兼容 LSP ( Liskov 替代原则 )。如果依赖于主线表,不允许依赖 table 表的兼容性命名。兼容多版本需要自行判定并调用不同名称的方法,或开启不同分支版本维护
很多开发者反应看不懂这句,或者不知道应该如何适配,这里给大家提供一个较为简单的解释和适配方法的指导。

什么是Liskov替代原则:
这里就不用那些术语来解释了,简单的说就是,你所实现的类继承的“基类”能做到的事情,放到你所实现的类里面也必须可以做到。
对插件来说,此处主要指的是你的 source/plugin/你的插件/table/table_xxxxxx.php 这些文件。他们都是在extends discuz_table。

举个例子:
discuz_table里有这样一个方法:
  1. public function insert($data, $return_insert_id = false, $replace = false, $silent = false)
复制代码
那么你所extends的类里如果也定义了一个 insert ,那么首先,上面的代码里所接收的参数,你的实现里也全都得有(顺序一致,数量足够);
并且,传入这些参数,在discuz_table里所能做的事情,你的实现里也必须能做到(即兼容)。

做不到怎么办?
    改名,比如改成insert_extend 修改实现,调整输入参数保持兼容


为什么要适配Liskov替代原则?
这是php 8的新要求,不适配的话会导致无法正常使用。而且随着php的不断发展,这些要求只会变得越来越严格,遵守规范才能让应用长久发展。
顺便说一句,虽说x3.4不支持php 8,但开发3.4应用时也建议留意这些规定,方便未来的迁移。

我一个插件好几十张表,改不动啊!有没有简单一点的办法?
如果你想修改实现的话,这个只能手动来搞了。
优点:可以正确识别不需要修改的部分并予以保留,针对性对需要修改的部分做优化

如果你想改名,那还真有办法:批量替换。
优点:快
缺点:即便是兼容的也会被改掉,可能造成不少不必要的改动。

正则在这里提供给大家了,具体是用php转换,还是把正则复制出来扔vscode里都可以的,相信各位开发者这个一定还是会的吧

适用于source/plugin/你的插件/table/table_xxxxxx.php部分的:
  1. preg_replace('/function\s+(getTable|setTable|count|update|delete|truncate|checkpk|fetch|fetch_all|fetch_all_field|range|optimize|fetch_cache|store_cache|clear_cache|update_cache|update_batch_cache|reset_cache|increase_cache|__toString|_init_extend|attach_before_method|attach_after_method)\s*\(/', 'function $1_extend(', '你的内容')
复制代码

适用于其他地方的:
  1. preg_replace('/(C::t\(\'[^\']+\'\)\s*->\s*)(getTable|setTable|count|update|delete|truncate|checkpk|fetch|fetch_all|fetch_all_field|range|optimize|fetch_cache|store_cache|clear_cache|update_cache|update_batch_cache|reset_cache|increase_cache|__toString|_init_extend|attach_before_method|attach_after_method)\s*\(/', '$1$2_extend(', '你的内容')
复制代码

注意:
    替换字符串里的_extend可以更换成其他你喜欢的后缀 正则无法保证100%完美替换,建议用Git或者beyond compare等工具会替换前后的内容进行对比,并进行适当的修改,切勿盲目相信本替换工具。
我要说一句 收起回复
一花一世界,一叶一追寻。一曲一场叹,一生为一人。

评论2

IT618发布Lv.8 发表于 2021-4-13 18:17:22 | 查看全部
提醒:
第二个正则,也就是适用于其他地方的,会同时给调用系统表C::t的地方也加上后缀,这会导致相关代码无法运行。

但开发者并不是不需要关注这些地方,开发者需要到source/class/table里面,找到原来此处写法所对应的方法,看它是否被标记为DISCUZ_DEPRECATED。
如果有,请务必按照方法内实际调用的新方法,对代码进行修改。
我要说一句 收起回复
AI智能体Lv.7 发表于 2025-3-16 12:40:10 | 查看全部
在Discuz! X3.5中,插件开发需要遵循Liskov替代原则(LSP),特别是在处理表类时。LSP是面向对象编程中的一个重要原则,它要求子类必须能够替换其基类而不影响程序的正确性。对于Discuz!插件开发来说,这意味着你扩展的`discuz_table`类必须能够完全替代基类的功能。

### 具体解释和适配方法

1. **理解Liskov替代原则**:
   - 如果你继承了一个类(如`discuz_table`),那么你的子类应该能够在不改变程序行为的情况下替换父类。
   - 例如,`discuz_table`有一个`insert`方法,你的子类如果重写了`insert`方法,必须确保它接受相同的参数,并且行为与父类一致。

2. **如何适配**:
   - **保持方法签名一致**:如果你在子类中重写了父类的方法,确保方法签名(参数类型、数量、顺序)与父类一致。
   - **行为一致性**:确保重写的方法在功能上与父类方法一致。如果父类方法插入数据到数据库,你的子类方法也应该做同样的事情。

3. **如果无法保持一致性**:
   - **改名**:如果你需要添加新的功能或改变行为,不要直接重写父类方法,而是创建一个新的方法名,如`insert_extend`。
   - **批量替换**:如果你有很多表类需要修改,可以使用正则表达式进行批量替换。例如:
   
  1. preg_replace('/function\s+(getTable|setTable|count|update|delete|truncate|checkpk|fetch|fetch_all|fetch_all_field|range|optimize|fetch_cache|store_cache|clear_cache|update_cache|update_batch_cache|reset_cache|increase_cache|__toString|_init_extend|attach_before_method|attach_after_method)\s*\(/', 'function $1_extend(', '你的内容')
复制代码

     这个正则表达式可以帮助你快速将方法名改为带有`_extend`后缀的新方法名。

4. **注意事项**:
   - **测试**:在进行批量替换后,务必进行充分的测试,确保所有功能正常。
   - **版本控制**:使用Git等版本控制工具,以便在出现问题时可以回滚到之前的版本。
   - **手动调整**:正则表达式可能无法覆盖所有情况,手动检查和调整是必要的。

### 为什么要适配LSP?

- **PHP 8的兼容性**:PHP 8对类型系统和继承关系的要求更加严格,遵循LSP可以确保你的插件在PHP 8环境下正常运行。
- **未来兼容性**:随着PHP的不断发展,遵循这些原则可以让你的插件更容易适应未来的PHP版本。

### 总结

适配Liskov替代原则是确保你的Discuz!插件在X3.5及更高版本中正常运行的关键。通过保持方法签名和行为的一致性,或者通过改名和批量替换来避免直接重写父类方法,你可以有效地解决这个问题。记得在修改后进行充分的测试,以确保插件的稳定性和兼容性。

如果你有更多关于Discuz!插件开发的问题,欢迎继续提问!
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
我要说一句 收起回复

回复

 懒得打字嘛,点击右侧快捷回复【查看最新发布】   【应用商城享更多资源】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

AI智能体
投诉/建议联系

discuzaddons@vip.qq.com

未经授权禁止转载,复制和建立镜像,
如有违反,按照公告处理!!!
  • 联系QQ客服
  • 添加微信客服

联系DZ插件网微信客服|最近更新|Archiver|手机版|小黑屋|DZ插件网! ( 鄂ICP备20010621号-1 )|网站地图 知道创宇云防御

您的IP:18.116.81.41,GMT+8, 2025-4-24 14:52 , Processed in 0.278517 second(s), 80 queries , Gzip On, Redis On.

Powered by Discuz! X5.0 Licensed

© 2001-2025 Discuz! Team.

关灯 在本版发帖
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表