Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method refactoring?

In the TokenRepository you can see 3 similar methods. It create new entry to the tokens table but each method has different fields.

How can I refactor this? Should I merge 3 methods into 1 method or should I use strategy pattern?

TokenRepository Class:

class TokenRepository
{
   public function createTokenDigitalOcean(User $user, $name, $accessToken, $refreshToken = null)
   {
        return $user->tokens()->create([
            'name'          => $name,
            'provider'      => 'digital_ocean',
            'access_token'  => $accessToken,
            'refresh_token' => $refreshToken,
        ]);
    }

    public function createTokenLinode(User $user, $name, $key)
    {
        return $user->tokens()->create([
            'name'       => $name,
            'provider'   => 'linode',
            'linode_key' => $key,
        ]);
    }

    public function createTokenAws(User $user, $name, $key, $secret)
    {
        return $user->tokens()->create([
            'name'       => $name,
            'provider'   => 'aws',
            'aws_key'    => $key,
            'aws_secret' => $secret,
        ]);
    }
}

I have 3 classes like DigitalOceanProvider, LinodeProvider and AwsProvider. For example of using LinodeProvider and AwsProvider class.

class LinodeProvider 
{
  public function callback()
  {
    $this->tokenRepo->createTokenLinode($user, $name, $key);
  }
}


class AwsProvider 
{
  public function callback()
  {
    $this->tokenRepo->createTokenAws($user, $name, $key, $secret);
  }
}
like image 662
I'll-Be-Back Avatar asked Nov 29 '16 15:11

I'll-Be-Back


1 Answers

This may be a bit overkill, but in order to make life a bit easier in the future, you could create separate implementations of each that extend an abstract class. This way you can unify and define the interface and easily add new token types.

<?php namespace Foo\Tokens;

abstract class Token
{
    protected $name = '';

    protected $key = '';

    protected $provider = '';

    public function __construct($name, $key)
    {
        $this->name = $name;
        $this->key = $key;
    }

    public function data()
    {
        return [
            'name' => $this->name,
            'provider' => $this->provider,
            'token' => $this->key
        ];
    }
}

Next, we create our Digital Ocean token class. This class can either use the default implementation or redefine it.

<?php namespace Foo\Tokens;

use Foo\Tokens\Token;

class DigitalOceanToken extends Token
{

    protected $provider = 'digital_ocean';

    public function __construct($name, $key, $refreshToken = null)
    {
        parent::__construct($name, $key);

        $this->refreshToken = $refreshToken;
    }

    public function data()
    {
        return [
            'name' => $this->name,
            'provider' => $this->provider,
            'key' => $this->key,
            'refreshToken' => $this->refreshToken
        ];
    }
}

The TokenRepository now merely cares about attaching a given token to a user.

<?php namespace Foo;

use User;
use Foo\Tokens\Token;

class TokenRepository
{
   public function createToken(User $user, Token $token)
   {
        return $user->tokens()->create(
            $token->data()
        );
    }
}

And your service providers are as simple as...

<?php 

use Foo\Tokens\AwsToken;

class AwsProvider
{
    public function callback()
    {
        $this->tokenRepo->createToken(
            $user, new AwsToken($name, $key, $secret)
        );
    }
}

This isn't working code, as I've not attempted to run it however it's just another idea of how you can organize and assign responsibility. Hope it helps, and welcome feedback from others.

like image 123
jardis Avatar answered Oct 04 '22 20:10

jardis