Pergunta

A base de código que fui entregue a trabalhar com recursos de uma classe de banco de dados que herda Mdb2. Isso forma a base para a estrutura do MVC em uso (um caso construído personalizado) e os modelos, por sua vez, herdam do banco de dados.

Como tenho certeza de que alguns de vocês notaram, isso leva a um grande problema. Toda vez que você instancia um modelo, o resultado é uma nova conexão de banco de dados que está sendo criada. Isso é obviamente um desperdício. Isso também significa que não consigo usar transações como pretendido, porque se uma transação iniciar em uma instância de um modelo, seus efeitos serão invisíveis para as outras instâncias até que ocorra uma confirmação.

Meu plano é alterar a classe DB para encapsular o MDB2 em vez de herdá -la e, em seguida, mantê -lo uma única instância do MDB2 por meio da funcionalidade Singleton.

No entanto, o MDB2 é uma grande biblioteca com muitos métodos, e muitas coisas mais altas na base de código depende de poder acessar os métodos MDB2.

Existe uma maneira de encapsular a classe MDB2 e transmitir chamadas sem modificar as camadas mais altas e sem precisar escrever um método de wrapper para todos os métodos no MDB2?

Foi útil?

Solução

Como você ainda não forneceu nenhum código, essa é uma sugestão cega de como você pode remover a herança com muito pouco código, e ao mesmo tempo, mantendo a funcionalidade completa e garantindo que a classe MDB seja instanciada apenas uma vez.

class Db
{
    protected static $_mdb;
    public function __construct()
    {
        if(self::_mdb === NULL) {
            self::_mdb = new MDB;
        }
    }
    public function __call($method, $args)
    {
        return call_user_func_array(array(self::_mdb, $method), $args);
    }
}

Isso basicamente fará com que o seu decorador de classe de banco de dados seja MDB. Na primeira instanciação, a classe DB criará e armazenará uma instância estática do MDB. Isso será compartilhado entre qualquer instância de banco de dados, incluindo aulas de crianças. Não há razão para usar um singleton aqui.

o __call O Interceptor garantirá que todos os métodos que você chamasse no DB que os métodos de chamada no método MDB sejam capturados e delegados na instância do MDB. Os métodos mágicos podem ter um impacto grave no desempenho; portanto, quando você perceber qualquer impacto de desempenho, adicione qualquer método chamado à classe DB e delegue a partir daí.

Escusado será dizer que essa ainda não é a melhor solução, porque sua instância de banco de dados ainda está bem acoplada às suas classes de modelo. Se você puder pagar mais refatoração, sugiro fazer todas as classes que atualmente herdam a partir do banco de dados encapsulam a instância do banco de dados (a menos que sejam contratados). Em seguida, use a injeção de dependência para disponibilizar a instância do banco de dados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top