Bernardo Benini Fantin
Bernardo Benini Fantin

Reputation: 103

Pattern for helping with code duplication

Recently I wrote a verification that catches exceptions and prevents the DB from persisting any data in that case. This piece of code seems like it's going to be used extensively in my code. So it raises a question: the begin of the code and end of it are alwas the same, the only thing that changes is what's in the middle. In this case, is there a pattern for not repeting it all the way in my code?

public function createGroupWith($data)
  {
    try {
      DB::beginTransaction();

      $modules_id = array_pop($data);

      $group = Group::create($data);
      $group->modules()->attach($modules_id);

      DB::commit();
      return ['msg' => trans('cms.groups.success_create')];
    } catch (\Throwable $error) {
      DB::rollBack();
      return ['msg' => $error->getMessage()];
    }
  }

Upvotes: 0

Views: 52

Answers (1)

StepUp
StepUp

Reputation: 38114

When you have a skeleton of methods and you want to override behaviour sometimes, then you can try to use Template Method pattern. As wiki says about Template method pattern:

the template method is one of the behavioral design patterns identified by Gamma et al.1 in the book Design Patterns. The template method is a method in a superclass, usually an abstract superclass, and defines the skeleton of an operation in terms of a number of high-level steps. These steps are themselves implemented by additional helper methods in the same class as the template method.

I am sorry, I do not know php, but give me a try to implement it.

abstract class Your class
{
    abstract protected function overridableBehaviour();     

    /** Template method */
    public final createGroupWith($data)
    {
        try {
          DB::beginTransaction();

          $this->overridableBehaviour();

          DB::commit();
          return ['msg' => trans('cms.groups.success_create')];
        } catch (\Throwable $error) {
          DB::rollBack();
          return ['msg' => $error->getMessage()];
        }
    }
}

It is possible to see php code example here:

abstract class Game
{
    abstract protected function initialize();
    abstract protected function startPlay();
    abstract protected function endPlay();

    /** Template method */
    public final function play()
    {
        /** Primitive */
        $this->initialize();

        /** Primitive */
        $this->startPlay();

        /** Primitive */
        $this->endPlay();
    }
}

and its concrete implementations:

class Mario extends Game
{
    protected function initialize()
    {
        echo "Mario Game Initialized! Start playing.", PHP_EOL;
    }

    protected function startPlay()
    {
        echo "Mario Game Started. Enjoy the game!", PHP_EOL;
    }

    protected function endPlay()
    {
        echo "Mario Game Finished!", PHP_EOL;
    }
}

and:

class Tankfight extends Game
{
    protected function initialize()
    {
        echo "Tankfight Game Initialized! Start playing.", PHP_EOL;
    }

    protected function startPlay()
    {
        echo "Tankfight Game Started. Enjoy the game!", PHP_EOL;
    }

    protected function endPlay()
    {
        echo "Tankfight Game Finished!", PHP_EOL;
    }    
}

and:

$game = new Tankfight();
$game->play();

$game = new Mario();
$game->play();

Upvotes: 1

Related Questions