专栏名称: SegmentFault思否
SegmentFault (www.sf.gg)开发者社区,是中国年轻开发者喜爱的极客社区,我们为开发者提供最纯粹的技术交流和分享平台。
目录
相关文章推荐
OSC开源社区  ·  Bun ... ·  16 小时前  
程序员的那些事  ·  OpenAI ... ·  昨天  
程序员小灰  ·  清华大学《DeepSeek学习手册》(全5册) ·  2 天前  
OSC开源社区  ·  2024: 大模型背景下知识图谱的理性回归 ·  3 天前  
OSC开源社区  ·  升级到Svelte ... ·  4 天前  
51好读  ›  专栏  ›  SegmentFault思否

如何成为一名优秀的工程师?——语义篇

SegmentFault思否  · 公众号  · 程序员  · 2019-03-05 08:00

正文

写在开头

本篇文章巨长,如果你比较“懒”,来我讲给你听(直播中有更多细节)——回放地址: https://segmentfault.com/l/1500000018225727

看完这个还不过瘾?学习使你快乐?还想学习?快上车: https://segmentfault.com/ls/1650000011318558

开始

好的语义表达是团队协作中高效迭代的润滑剂,好的语义表达是线上未知代码问题排查的指南针。

不要让其他人读不懂你的代码,其他人可能就是一周后的你。时刻以“如果你写的这段代码出现故障,一个陌生人接手你的代码需要多久能处理完这个bug”来监督自己。

日常中应该多多刻意提升自己语义表达,百利而无一害。那么我们应该从哪些细节去做好语义表达呢?

以下代码全为我的艺术创作,不属于任何实际项目

命名

案例1
  1. function getGoods($query, $shopId)

  2. {

  3. $goodsId = Goods::add($query["uid"], $query["name"]);

  4. return Shop::add($goodsId, $shopId);

  5. }


  6. class Goods

  7. {

  8. public static function add($uid, $name)

  9. {

  10. $id = mt_rand(1, 100000);

  11. return $id;

  12. }

  13. }


  14. class Shop

  15. {

  16. public static function add($goodsId, $shopId)

  17. {

  18. $id = mt_rand(1, 100000);

  19. return $id;

  20. }

  21. }

案例2
  1. function getUserInfo($teamId, $youId = [])

  2. {


  3. }

如果仅仅有这个函数名和参数名,谁能猜到参数的意义呢?

案例3
  1. class Db

  2. {

  3. /**

  4. * @param string $table 数据库表名

  5. * @param array $data 新增数据

  6. *

  7. * @return int 新增主键

  8. */

  9. public static function insert(string $table, array $data)

  10. {

  11. $id = mt_rand(1, 1000);

  12. return $id;

  13. }

  14. }


  15. class ViewLogStore

  16. {

  17. private $table = "view_log";


  18. function setHistory($data)

  19. {

  20. Db::insert($this->table, $data);

  21. }

  22. }

案例4

假如业务代码里有这些类:

  1. class WechatUserModel{


  2. }


  3. class WechatGroupModel{


  4. }


  5. class WechatMessageModel{


  6. }

而我们查询数据库发现:

这样我们根据业务代码就非常不方便找到对应的表,而且其他人接手我们项目的时候,也会摸不着头脑。或者说这可能是三个人三次迭代开发造成的,那么他们彼此都没有去参考前面人的命名规则。

来自灵魂的拷问

注释

说完命名,下面说下注释。注释里还有什么学问?Are you kidding me?

那么,

一个数组对象成员,你知道怎么写吗?

类的魔术方法调用的注释,你知道怎么写吗?

对象数组
  1. /**

  2. * @var Ads[]

  3. */

  4. public $adsList = [];

  1. $blocks = [];/** @var $blocks Block[] **/

@method 的使用
  1. /**

  2. * @link http://manual.phpdoc.org/HTMLframesConverter/default/

  3. *

  4. * @method static int search(string $query, $limit = 10, $offset = 0)

  5. */

  6. class SearchServiceProxy

  7. {

  8. public static function __callStatic($method, $arguments)

  9. {

  10. if (!method_exists("SearchService", $method)) {

  11. throw new \LogicException(__CLASS__ . "::" . $method . " not found");

  12. }


  13. try {

  14. $data = call_user_func_array(["SearchService", $method], $arguments);

  15. } catch (\Exception $e) {

  16. error_log($e->getMessage());

  17. return false;

  18. }


  19. return $data;

  20. }

  21. }

@deprecated 使用
  1. class SearchService

  2. {


  3. /**

  4. * @param string $query

  5. * @param int $limit

  6. * @param int $offset

  7. *

  8. * @return array

  9. * @deprecated

  10. */

  11. public static function search(string $query, $limit = 10, $offset = 0)

  12. {

  13. return [

  14. ["id" => 1, "aaa"],

  15. ["id" => 2, "bbb"],

  16. ];

  17. }

  18. }

注释其他注意事项

注释解释张冠李戴,方法名更新,方法的功能业务注释没更新;复制别人的代码把 @author 信息也复制过来了,错误了还要把锅甩给别人。

注释更多参考 http://manual.phpdoc.org/HTMLframesConverter/default/

函数、方法

案例1

先说明一句,不好的代码不妨碍它成为一个优秀的软件。PHP MySQL 烂代码多的去了。

找到一个开源软件里面的代码,功能非常抢到,但是这个方法内容太多,一些不足点我标注出来了。

案例2

拿上面我举例子,还记得下面这种图吗?

优化方案1

  1. class ArrayUtils{

  2. public static function fetch($arr, $keys, $setNull = false)

  3. {

  4. $ret = array();

  5. foreach($keys as $key)

  6. {

  7. if ($setNull)

  8. {

  9. $ret[$key] = $arr[$key];

  10. }

  11. else

  12. {

  13. isset($arr[$key]) && $ret[$key] = $arr[$key];

  14. }

  15. }

  16. return $ret;

  17. }

  18. }


  19. class ViewLogStore

  20. {

  21. private $table = "view_log" ;


  22. function record($data)

  23. {

  24. $fields = array(

  25. 'uid',

  26. 'url',

  27. 'referer',

  28. 'created_time'

  29. );

  30. $data = ArrayUtils::fetch($data, $fields);

  31. Db::insert($this->table, $data);

  32. }

  33. }

优化方案2

  1. class Db

  2. {

  3. /**

  4. * @param string $table 数据库表名

  5. * @param Entity $data 新增对象

  6. *

  7. * @return int 新增主键

  8. */

  9. public static function insert(string $table, Entity $data)

  10. {

  11. $array = $data->toArray();

  12. var_export($array); // test


  13. $id = mt_rand(1, 1000);

  14. return $id;

  15. }

  16. }


  17. class ArrayUtils

  18. {

  19. /**

  20. * 针对成员都是私有属性的对象

  21. *

  22. * @param $obj

  23. * @param bool $removeNull 去掉空值

  24. * @param bool $camelCase

  25. *

  26. * @return array

  27. */

  28. public static function Obj2Array($obj, $removeNull = true, $camelCase = true)

  29. {

  30. $reflect = new \ReflectionClass($obj);

  31. $props = $reflect->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PRIVATE | \ReflectionProperty::IS_PROTECTED);


  32. $array = [];

  33. foreach ( $props as $prop) {

  34. $prop->setAccessible(true);

  35. $key = $prop->getName();


  36. // 如果不是驼峰命名方式,就把对象里面的 createTime 转成 create_time

  37. if (!$camelCase) {

  38. $key = preg_replace_callback("/[A-Z]/", function ($matches) {

  39. return "_" . strtolower($matches[0]);

  40. }, $key);

  41. $key = ltrim($key, "_");

  42. }


  43. $value = $prop->getValue($obj);


  44. if ($removeNull == true && $value === null) {

  45. continue;

  46. }


  47. if (is_object($value)) {

  48. $value = self::Obj2Array($value);

  49. }


  50. $array[$key] = $value;

  51. }


  52. return $array;

  53. }

  54. }


  55. class Entity

  56. {

  57. public function toArray(){

  58. return ArrayUtils::Obj2Array($this);

  59. }

  60. }


  61. class ViewLogEntity extends Entity

  62. {

  63. /**

  64. * @var int

  65. */

  66. private $uid;


  67. /**

  68. * @var string

  69. */

  70. private $url;


  71. /**

  72. * @var string

  73. */

  74. private $referer;


  75. /**

  76. * @var string

  77. */

  78. private $createdTime;


  79. /**

  80. * @param int $uid

  81. */







请到「今天看啥」查看全文