Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Card often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Card, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 29 | class Card extends AbstractAPI |
||
| 30 | { |
||
| 31 | /** |
||
| 32 | * Cache. |
||
| 33 | * |
||
| 34 | * @var Cache |
||
| 35 | */ |
||
| 36 | protected $cache; |
||
| 37 | |||
| 38 | /** |
||
| 39 | * Ticket cache prefix. |
||
| 40 | */ |
||
| 41 | const TICKET_CACHE_PREFIX = 'overtrue.wechat.card_api_ticket.'; |
||
| 42 | |||
| 43 | const API_GET_COLORS = 'https://api.weixin.qq.com/card/getcolors'; |
||
| 44 | const API_CREATE = 'https://api.weixin.qq.com/card/create'; |
||
| 45 | const API_QRCODE_CREATE = 'https://api.weixin.qq.com/card/qrcode/create'; |
||
| 46 | const API_QRCODE_SHOW = 'https://mp.weixin.qq.com/cgi-bin/showqrcode'; |
||
| 47 | const API_GET_CARD_TICKET = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket'; |
||
| 48 | const API_LANDING_PAGE = 'https://api.weixin.qq.com/card/landingpage/create'; |
||
| 49 | const API_DEPOSIT = 'https://api.weixin.qq.com/card/code/deposit'; |
||
| 50 | const API_GET_DEPOSIT_COUNT = 'https://api.weixin.qq.com/card/code/getdepositcount'; |
||
| 51 | const API_CHECK_CODE = 'https://api.weixin.qq.com/card/code/checkcode'; |
||
| 52 | const API_GET_HTML = 'https://api.weixin.qq.com/card/mpnews/gethtml'; |
||
| 53 | const API_TEST_WHITE_LIST = 'https://api.weixin.qq.com/card/testwhitelist/set'; |
||
| 54 | const API_CODE_GET = 'https://api.weixin.qq.com/card/code/get'; |
||
| 55 | const API_CONSUME = 'https://api.weixin.qq.com/card/code/consume'; |
||
| 56 | const API_DECRYPT = 'https://api.weixin.qq.com/card/code/decrypt'; |
||
| 57 | const API_GET_CARD_LIST = 'https://api.weixin.qq.com/card/user/getcardlist'; |
||
| 58 | const API_CARD_GET = 'https://api.weixin.qq.com/card/get'; |
||
| 59 | const API_BATCH_GET = 'https://api.weixin.qq.com/card/batchget'; |
||
| 60 | const API_UPDATE = 'https://api.weixin.qq.com/card/update'; |
||
| 61 | const API_PAY_CELL_SET = 'https://api.weixin.qq.com/card/paycell/set'; |
||
| 62 | const API_MODIFY_STOCK = 'https://api.weixin.qq.com/card/modifystock'; |
||
| 63 | const API_CODE_UPDATE = 'https://api.weixin.qq.com/card/code/update'; |
||
| 64 | const API_CARD_DELETE = 'https://api.weixin.qq.com/card/delete'; |
||
| 65 | const API_UNAVAILABLE = 'https://api.weixin.qq.com/card/code/unavailable'; |
||
| 66 | const API_CARD_BIZ_UIN_INFO = 'https://api.weixin.qq.com/datacube/getcardbizuininfo'; |
||
| 67 | const API_CARD_CARD_INFO = 'https://api.weixin.qq.com/datacube/getcardcardinfo'; |
||
| 68 | const API_CARD_MEMBER_CARD_INFO = 'https://api.weixin.qq.com/datacube/getcardmembercardinfo'; |
||
| 69 | const API_CARD_ACTIVATE = 'https://api.weixin.qq.com/card/membercard/activate'; |
||
| 70 | const API_ACTIVATE_USER_FORM = 'https://api.weixin.qq.com/card/membercard/activateuserform/set'; |
||
| 71 | const API_MEMBER_USER_INFO = 'https://api.weixin.qq.com/card/membercard/userinfo/get'; |
||
| 72 | const API_UPDATE_USER = 'https://api.weixin.qq.com/card/membercard/updateuser'; |
||
| 73 | const API_SUB_MERCHANT = 'https://api.weixin.qq.com/card/submerchant/submit'; |
||
| 74 | const API_GET_APPLY_PROTOCOL = 'https://api.weixin.qq.com/card/getapplyprotocol'; |
||
| 75 | |||
| 76 | /** |
||
| 77 | * 获取卡券颜色 |
||
| 78 | * |
||
| 79 | * @return array |
||
| 80 | */ |
||
| 81 | public function getColors() |
||
| 85 | |||
| 86 | /** |
||
| 87 | * 创建卡券 |
||
| 88 | * |
||
| 89 | * @param string $card_type |
||
| 90 | * @param array $base_info |
||
| 91 | * @param array $especial |
||
| 92 | * @param array $advanced_info |
||
| 93 | * |
||
| 94 | * @return bool|array |
||
| 95 | */ |
||
| 96 | public function create($card_type = 'member_card', $base_info = [], $especial = [], $advanced_info = []) |
||
| 116 | |||
| 117 | /** |
||
| 118 | * 创建二维码 |
||
| 119 | * |
||
| 120 | * @param array $card_list |
||
| 121 | * |
||
| 122 | * @return array|bool |
||
| 123 | */ |
||
| 124 | public function qrCode($card_list = []) |
||
| 128 | |||
| 129 | /** |
||
| 130 | * ticket 换取二维码图片 |
||
| 131 | * |
||
| 132 | * @param null $ticket |
||
| 133 | * |
||
| 134 | * @return array |
||
| 135 | */ |
||
| 136 | public function showQrCode($ticket = null) |
||
| 155 | |||
| 156 | /** |
||
| 157 | * 通过ticket换取二维码 链接 |
||
| 158 | * |
||
| 159 | * @param $ticket |
||
| 160 | * |
||
| 161 | * @return string |
||
| 162 | */ |
||
| 163 | public function showQrCode_Url($ticket) |
||
| 169 | |||
| 170 | /** |
||
| 171 | * 获取 卡券 Api_ticket |
||
| 172 | * |
||
| 173 | * @param boolean $jus 是否强制刷新 |
||
| 174 | * |
||
| 175 | * @return string $api_ticket api_ticket |
||
| 176 | */ |
||
| 177 | public function cardApiTicket($jus = false) |
||
| 193 | |||
| 194 | /** |
||
| 195 | * 微信卡券:JSAPI 卡券Package - 基础参数没有附带任何值 - 再生产环境中需要根据实际情况进行修改 |
||
| 196 | * |
||
| 197 | * @param array $card_list |
||
| 198 | * @param null $timestamp |
||
| 199 | * @param null $api_ticket |
||
| 200 | * |
||
| 201 | * @return string |
||
| 202 | */ |
||
| 203 | public function wxCardPackage(array $card_list, $timestamp = null, $api_ticket = null) |
||
| 245 | |||
| 246 | /** |
||
| 247 | * 创建货架接口 |
||
| 248 | * |
||
| 249 | * @param $banner |
||
| 250 | * @param $page_title |
||
| 251 | * @param $can_share |
||
| 252 | * @param $scene |
||
| 253 | * @param $card_list |
||
| 254 | * |
||
| 255 | * @return array |
||
| 256 | */ |
||
| 257 | public function landingPage($banner, $page_title, $can_share, $scene, $card_list) |
||
| 269 | |||
| 270 | /** |
||
| 271 | * 导入code接口 |
||
| 272 | * |
||
| 273 | * @param $card_id |
||
| 274 | * @param $code |
||
| 275 | * |
||
| 276 | * @return array |
||
| 277 | */ |
||
| 278 | View Code Duplication | public function deposit($card_id, $code) |
|
| 287 | |||
| 288 | /** |
||
| 289 | * 查询导入code数目 |
||
| 290 | * |
||
| 291 | * @param $card_id |
||
| 292 | * |
||
| 293 | * @return array |
||
| 294 | */ |
||
| 295 | View Code Duplication | public function getDepositCount($card_id) |
|
| 303 | |||
| 304 | /** |
||
| 305 | * 核查code接口 |
||
| 306 | * |
||
| 307 | * @param $card_id |
||
| 308 | * @param $code |
||
| 309 | * |
||
| 310 | * @return array |
||
| 311 | */ |
||
| 312 | View Code Duplication | public function checkCode($card_id, $code) |
|
| 321 | |||
| 322 | /** |
||
| 323 | * 图文消息群发卡券 |
||
| 324 | * |
||
| 325 | * @param $card_id |
||
| 326 | * |
||
| 327 | * @return array |
||
| 328 | */ |
||
| 329 | View Code Duplication | public function getHtml($card_id) |
|
| 337 | |||
| 338 | /** |
||
| 339 | * 设置测试白名单 |
||
| 340 | * |
||
| 341 | * @param $openid |
||
| 342 | * @param $username |
||
| 343 | * |
||
| 344 | * @return array |
||
| 345 | */ |
||
| 346 | public function testWhiteList($openid, $username) |
||
| 355 | |||
| 356 | /** |
||
| 357 | * 查询Code接口 |
||
| 358 | * |
||
| 359 | * @param $code |
||
| 360 | * @param $check_consume |
||
| 361 | * @param $card_id |
||
| 362 | * |
||
| 363 | * @return array |
||
| 364 | */ |
||
| 365 | public function codeGet($code, $check_consume, $card_id) |
||
| 375 | |||
| 376 | /** |
||
| 377 | * 核销Code接口 |
||
| 378 | * |
||
| 379 | * @param $card_id |
||
| 380 | * @param $code |
||
| 381 | * |
||
| 382 | * @return array |
||
| 383 | */ |
||
| 384 | public function consume($card_id, $code) |
||
| 393 | |||
| 394 | /** |
||
| 395 | * Code解码接口 |
||
| 396 | * |
||
| 397 | * @param $encrypt_code |
||
| 398 | * |
||
| 399 | * @return array |
||
| 400 | */ |
||
| 401 | View Code Duplication | public function decrypt($encrypt_code) |
|
| 409 | |||
| 410 | /** |
||
| 411 | * 获取用户已领取卡券接口 |
||
| 412 | * |
||
| 413 | * @param $openid |
||
| 414 | * @param string $card_id |
||
| 415 | * |
||
| 416 | * @return array |
||
| 417 | */ |
||
| 418 | public function getCardList($openid, $card_id = '') |
||
| 427 | |||
| 428 | /** |
||
| 429 | * 查看卡券详情 |
||
| 430 | * |
||
| 431 | * @param $card_id |
||
| 432 | * |
||
| 433 | * @return array |
||
| 434 | */ |
||
| 435 | public function cardGet($card_id) |
||
| 443 | |||
| 444 | /** |
||
| 445 | * 批量查询卡列表 |
||
| 446 | * |
||
| 447 | * @param int $offset |
||
| 448 | * @param int $count |
||
| 449 | * @param string $status_list |
||
| 450 | * |
||
| 451 | * @return array |
||
| 452 | */ |
||
| 453 | View Code Duplication | public function batchGet($offset = 0, $count = 10, $status_list = 'CARD_STATUS_VERIFY_OK') |
|
| 463 | |||
| 464 | /** |
||
| 465 | * 更改卡券信息接口 and 设置跟随推荐接口 |
||
| 466 | * |
||
| 467 | * @param $card_id |
||
| 468 | * @param $type |
||
| 469 | * @param array $base_info |
||
| 470 | * @param array $especial |
||
| 471 | * |
||
| 472 | * @return array |
||
| 473 | */ |
||
| 474 | public function update($card_id, $type, $base_info = [], $especial = []) |
||
| 487 | |||
| 488 | /** |
||
| 489 | * 设置微信买单接口 |
||
| 490 | * 设置买单的card_id必须已经配置了门店,否则会报错 |
||
| 491 | * |
||
| 492 | * @param $card_id |
||
| 493 | * @param bool $is_open |
||
| 494 | * |
||
| 495 | * @return array |
||
| 496 | */ |
||
| 497 | public function payCellSet($card_id, $is_open = true) |
||
| 506 | |||
| 507 | /** |
||
| 508 | * 修改库存接口 |
||
| 509 | * |
||
| 510 | * @param $card_id |
||
| 511 | * @param string $stock |
||
| 512 | * @param int $value |
||
| 513 | * |
||
| 514 | * @return array |
||
| 515 | */ |
||
| 516 | public function modifyStock($card_id, $stock = 'increase', $value = 0) |
||
| 530 | |||
| 531 | /** |
||
| 532 | * 更改Code接口 |
||
| 533 | * |
||
| 534 | * @param $code |
||
| 535 | * @param $new_code |
||
| 536 | * @param array $card_id |
||
| 537 | * |
||
| 538 | * @return array |
||
| 539 | */ |
||
| 540 | public function codeUpdate($code, $new_code, $card_id = []) |
||
| 550 | |||
| 551 | /** |
||
| 552 | * 删除卡券接口 |
||
| 553 | * |
||
| 554 | * @param $card_id |
||
| 555 | * |
||
| 556 | * @return array |
||
| 557 | */ |
||
| 558 | public function cardDelete($card_id) |
||
| 566 | |||
| 567 | /** |
||
| 568 | * 设置卡券失效 |
||
| 569 | * |
||
| 570 | * @param $code |
||
| 571 | * @param null $card_id |
||
| 572 | * |
||
| 573 | * @return array |
||
| 574 | */ |
||
| 575 | public function unavailable($code, $card_id = null) |
||
| 584 | |||
| 585 | /** |
||
| 586 | * 拉取卡券概况数据接口 |
||
| 587 | * |
||
| 588 | * @param $begin_date |
||
| 589 | * @param $end_date |
||
| 590 | * @param int $cond_source |
||
| 591 | * |
||
| 592 | * @return array |
||
| 593 | */ |
||
| 594 | public function getCardBizUinInfo($begin_date, $end_date, $cond_source = 0) |
||
| 612 | |||
| 613 | /** |
||
| 614 | * 获取免费券数据接口 |
||
| 615 | * |
||
| 616 | * @param $begin_date |
||
| 617 | * @param $end_date |
||
| 618 | * @param int $cond_source |
||
| 619 | * @param string $card_id |
||
| 620 | * |
||
| 621 | * @return array |
||
| 622 | */ |
||
| 623 | View Code Duplication | public function getCardCardInfo($begin_date, $end_date, $cond_source = 0, $card_id = '') |
|
| 634 | |||
| 635 | /** |
||
| 636 | * 拉取会员卡数据接口 |
||
| 637 | * |
||
| 638 | * @param $begin_date |
||
| 639 | * @param $end_date |
||
| 640 | * @param int $cond_source |
||
| 641 | * |
||
| 642 | * @return array |
||
| 643 | */ |
||
| 644 | View Code Duplication | public function getCardMemberCardInfo($begin_date, $end_date, $cond_source = 0) |
|
| 654 | |||
| 655 | /** |
||
| 656 | * 会员卡接口激活 |
||
| 657 | * |
||
| 658 | * @param array $activate |
||
| 659 | * |
||
| 660 | * @return array |
||
| 661 | */ |
||
| 662 | public function activate($activate = []) |
||
| 666 | |||
| 667 | /** |
||
| 668 | * 设置开卡字段接口 |
||
| 669 | * |
||
| 670 | * @param $card_id |
||
| 671 | * @param array $required_form |
||
| 672 | * @param array $optional_form |
||
| 673 | * |
||
| 674 | * @return array |
||
| 675 | */ |
||
| 676 | public function activateUserFrom($card_id, $required_form = [], $optional_form = []) |
||
| 685 | |||
| 686 | /** |
||
| 687 | * 拉取会员信息接口 |
||
| 688 | * |
||
| 689 | * @param $card_id |
||
| 690 | * @param $code |
||
| 691 | * |
||
| 692 | * @return array |
||
| 693 | */ |
||
| 694 | public function memberCardUserInfo($card_id, $code) |
||
| 703 | |||
| 704 | /** |
||
| 705 | * 更新会员信息 |
||
| 706 | * |
||
| 707 | * @param array $updateUser |
||
| 708 | * |
||
| 709 | * @return array |
||
| 710 | */ |
||
| 711 | public function memberCardUpdateUser($updateUser = []) |
||
| 717 | |||
| 718 | /** |
||
| 719 | * 添加子商户 |
||
| 720 | * |
||
| 721 | * @param $brand_name |
||
| 722 | * @param $logo_url |
||
| 723 | * @param $protocol |
||
| 724 | * @param $end_time |
||
| 725 | * @param $primary_category_id |
||
| 726 | * @param $secondary_category_id |
||
| 727 | * @param $agreement_media_id |
||
| 728 | * @param $operator_media_id |
||
| 729 | * @param string $app_id |
||
| 730 | * |
||
| 731 | * @return array |
||
| 732 | */ |
||
| 733 | public function subMerchant($brand_name, $logo_url, $protocol, $end_time, $primary_category_id, $secondary_category_id, $agreement_media_id, $operator_media_id, $app_id = '') |
||
| 751 | |||
| 752 | /** |
||
| 753 | * 卡券开放类目查询接口 |
||
| 754 | * |
||
| 755 | * @return array|bool |
||
| 756 | */ |
||
| 757 | public function getApplyProtocol() |
||
| 761 | |||
| 762 | /** |
||
| 763 | * Set cache manager. |
||
| 764 | * |
||
| 765 | * @param \Doctrine\Common\Cache\Cache $cache |
||
| 766 | * |
||
| 767 | * @return $this |
||
| 768 | */ |
||
| 769 | public function setCache(Cache $cache) |
||
| 775 | |||
| 776 | /** |
||
| 777 | * Return cache manager. |
||
| 778 | * |
||
| 779 | * @return \Doctrine\Common\Cache\Cache |
||
| 780 | */ |
||
| 781 | public function getCache() |
||
| 785 | } |
||
| 786 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.