要统一多个不同但部分逻辑相似的接口成一个 API 接口,可以采用策略模式(Strategy Pattern)来实现。这种设计模式允许你定义一组算法,将它们封装起来,并且使它们可以互相替换。策略模式使得算法可以独立于使用它的客户而变化。
步骤
- 定义策略接口
- 实现具体策略
- 创建策略上下文类
- 在控制器中使用策略上下文类
- 配置路由
1. 定义策略接口
首先,定义一个策略接口,所有具体的扣积分策略都将实现这个接口。
1 2 3 4 5 6 7 8 9 10 11
| <?php
namespace App\Services\Points;
use App\Models\User; use Illuminate\Http\Request;
interface PointsStrategy { public function execute(User $user, Request $request): bool; }
|
2. 实现具体策略
为每个不同的扣积分操作实现具体的策略。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| <?php
namespace App\Services\Points;
use App\Models\User; use Illuminate\Http\Request;
class CouponDeductPointsStrategy implements PointsStrategy { public function execute(User $user, Request $request): bool { return true; } }
class EnergyCouponDeductPointsStrategy implements PointsStrategy { public function execute(User $user, Request $request): bool { return true; } }
class MiniProgramCheckInDeductPointsStrategy implements PointsStrategy { public function execute(User $user, Request $request): bool { return true; } }
class AdminAdjustPointsStrategy implements PointsStrategy { public function execute(User $user, Request $request): bool { return true; } }
|
3. 创建策略上下文类
创建一个上下文类,用于根据请求选择合适的策略并执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <?php
namespace App\Services\Points;
use Illuminate\Http\Request; use App\Models\User;
class PointsContext { protected $strategy;
public function __construct(PointsStrategy $strategy) { $this->strategy = $strategy; }
public function executeStrategy(User $user, Request $request): bool { return $this->strategy->execute($user, $request); } }
|
4. 在控制器中使用策略上下文类
在控制器中,根据请求中的参数选择合适的策略,并通过上下文类执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <?php
namespace App\Http\Controllers;
use App\Models\User; use App\Services\Points\PointsContext; use App\Services\Points\CouponDeductPointsStrategy; use App\Services\Points\EnergyCouponDeductPointsStrategy; use App\Services\Points\MiniProgramCheckInDeductPointsStrategy; use App\Services\Points\AdminAdjustPointsStrategy; use Illuminate\Http\Request;
class PointsController extends Controller { public function deductPoints(Request $request, User $user) { $type = $request->input('type');
switch ($type) { case 'coupon': $strategy = new CouponDeductPointsStrategy(); break; case 'energy_coupon': $strategy = new EnergyCouponDeductPointsStrategy(); break; case 'mini_program_checkin': $strategy = new MiniProgramCheckInDeductPointsStrategy(); break; case 'admin_adjust': $strategy = new AdminAdjustPointsStrategy(); break; default: return response()->json(['message' => 'Invalid type.'], 400); }
$context = new PointsContext($strategy); $success = $context->executeStrategy($user, $request);
if ($success) { return response()->json(['message' => 'Operation successful.']); }
return response()->json(['message' => 'Operation failed.'], 400); } }
|
5. 配置路由
在 routes/web.php 或 routes/api.php 中配置路由:
1 2 3
| use App\Http\Controllers\PointsController;
Route::post('/points/deduct/{user}', [PointsController::class, 'deductPoints']);
|
总结
通过以上步骤,我们将多个不同的扣积分接口统一成一个 API 接口。我们使用策略模式来定义和实现不同的扣积分逻辑,根据请求的参数选择合适的策略,从而实现统一的接口。这样不仅减少了代码重复,还提高了代码的可维护性和可扩展性。