Should I use abstract class or interface?

Asked

Viewed 454 times

3

I have a class that connects to Windows machines. I’m making it a little more generic so I can repurpose it to other systems.

Soon I was able to identify four methods "generic":

  • connect
  • status
  • message
  • execute

With this, I set up a class and an interface, but my question is the following: In the scenario below, it is better to use an abstract class, or an interface is more than enough?

Connection class:

class Windows implements Conector
{
    /**
     * Armazena um apontamento externo para um recurso
     * 
     * @access private
     * @var object
     */
    private static $conexao;

    /**
     * Armazena a(s) mensagens de erro
     * 
     * @access private
     * @var string
     */
    private static $mensagemErro;

    /**
     * Método de conexão
     * 
     * @param   string $host
     * @param   string $usuario
     * @param   string $senha
     * @param   int $porta
     * @param   int $timeout
     * @return  void
     */
    public static function conectar($host, $usuario = null, $senha = null, $porta = 135, $timeout = 10)
    {
        try
        {
            /**
             * Método utilizado para testar conectividade com o host alvo
             * 
             * @param string $host
             * @param string $porta
             * @param int    $errno valor de sistema
             * @param string $errstr mensagem de sistema
             * @param int    $timeout tempo máximo a esperar por uma tentativa de conexão via socket
             */    
            if (!@fsockopen($host, $porta, $errno, $errstr, $timeout))
            {
                throw new Exception("Erro ({$errno}): Time Out ao chamar o host <b>{$host}</b>!");
            }

            //...

        } catch (Exception $e) {
            self::$mensagemErro =  $e->getMessage();
        }
    }

    public static function status()
    {
        return (self::$conexao !== NULL) ? TRUE : FALSE;
    }

    public static function mensagemErro()
    {
        return self::$mensagemErro;
    }

    public static function executar($acao)
    {
        try
        {
            if (!self::$conexao)
            {
                throw new Exception("Erro: É necessário abrir uma conexão antes de tentar executar qualquer comando!");
            }
             // @see http://php.net/manual/en/ref.com.php
            return self::$conexao->ExecQuery($query);
        }
        catch (Exception $e)
        {
            return $e->getMessage();
        }
    }

}

Interface:

interface Conector
{
    /**
     * Método de conexão para máquinas Windows
     * 
     * @param   string $host
     * @param   string $usuario
     * @param   string $senha
     * @param   int $porta
     * @param   int $timeout
     * @return  void
     */
    public static function conectar($host, $usuario = null, $senha = null, $porta = 135, $timeout = 10);

    public static function status();

    public static function mensagemErro();

    public static function executar($acao);
}
  • Thanks @bigown. I’ve moved up the project: https://github.com/crphp

1 answer

5


If you want to do it right, neither. At least with the names used. A class called Windows, which I already find strange, it doesn’t seem like I should inherit or implement a Conector. That seems like error of design.

But if you want to insist interface should be preferred whenever possible. It seems in this case it’s possible, so you should do it anyway.

If you wanted to have standard implementations in these methods then the interface would no longer be possible. But a trait could be the solution (has question about it, another).

If you need states (variables) and not only behaviors (methods), then only the abstract class will solve. On second thought, the class that implements the interface had to create variables. Is that what you wanted? Leave all the implementation details for the class to decide how to do? If so, great. If it was not the intention, if it wanted to provide already implemented in this way in the class, and who knows how to let the class overlap, or not, then the class should be abstract, at least.

If all behaviors are implemented in this class and you think it is useful that it be instantiated by itself in some situation, then the class must be concrete.

One more Already asked question answers that (there was another, follow the links).

Addendum

All these static members seem to be a mistake. If it is to do this, do everything procedural, I saw no advantage to do this way.

I consider the use of the exception there wrong, but this is something I almost gave up, almost everyone does wrong. I’ve said a lot about this, I will not repeat here. Actually this was one of the biggest abuses I have ever seen in codes. In this case it is not only wrong, it is completely unnecessary.

The method status is doing something redundant.

That is, it seems that you are trying to get an advanced concept when you do not yet master basic aspects of language. I would not go down that path. But hardly anyone listens.

Just as OOP exaggeration in PHP. See also: PHP mixes object-oriented codes and procedural language?.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.