Pergunta

Atualmente estou trabalhando em uma base de código que tem muitas classes que implementam um método Start. Isso me parece uma construção em duas fases, que sempre considerei uma prática ruim.Eu não posso dizer a diferença entre isso e um construtor.

Quando é apropriado usar um método start em vez da construção normal de objetos?

Quando devo preferir usar o construtor?

Edit: Eu não acho que seja tão relevante, mas a linguagem de programação é C#, pode ser aplicada igualmente a Java ou C++

Foi útil?

Solução

Um método Start() (como Run(), Execute() ou algo semelhante) é apropriado quando o custo de construção do objeto é baixo, mas o custo de uso é alto.Por exemplo: Uma classe que encapsula um algoritmo de otimização de melhor caminho.É trivial configurá-lo com um conjunto de parâmetros (X quadrados por Y quadrados, com o método de avaliação tal e tal), mas pode demorar um pouco para ser executado.Se você quiser criar 20 desses objetos, você pode querer atrasar a execução até que todos eles tenham sido criados - isso permite paralelizá-los mais facilmente, por exemplo.

Como alternativa, pode ser útil quando você não sabe quando o objeto será necessário para iniciar - talvez porque seja baseado na entrada do usuário ou na lógica que seleciona de uma lista de possibilidades.

Isso pressupõe, é claro, que Start() seja o método útil no objeto, e não um método equivalente a Initialize().Se for apenas uma maneira extra de definir mais parâmetros, não deveria existir.

Outras dicas

Código Completo (e muitos outros recursos de engenharia de software) enfatiza a correspondência de suas classes com objetos do mundo real.Acredito que a razão fundamental para isso é que torna mais provável que você tenha uma verdadeira compreensão do que está implementando, em vez de cortar uma ideia intangível.

Se você é um assinante dessa teoria, não vejo nada de errado em adicionar um método Start() a qualquer classe que deveria, se fosse um objeto real, também ter um estado de repouso.Se não faz nenhum sentido que seu objeto exista enquanto não está em execução (ou não faz nenhum sentido que seu objeto esteja em execução), então eu diria que é uma má prática.

Você pode usar inicialização lenta.

Na programação de computadores, a inicialização lenta é a tática de atrasar a criação de um objeto, o cálculo de um valor ou algum outro processo caro até a primeira vez que for necessário.

Dessa forma, você evita o acoplamento temporal, o que significa que o consumidor de sua classe precisa chamar determinados métodos em determinada ordem.Ter que ligar primeiro para o start() é uma forma de ter que saber como a classe funciona internamente, o que é ruim porque você pode mudar isso no futuro.

Atrase a inicialização cara até que seja necessária.

Exemplo:

public class FooClass{

    private ExpensiveResource resource;
    private CheapResource cheap;

    public  FooClass(String someParameter){
        // constructor: initialize CheapResource cheap 
            // but NOT ExpensiveResource resource
    }

    public ExpensiveResource getExpensiveResource(){
        if (resource == null) {
            this.initializeExpensiveResource();     
        }
        return this.resource
    }

    public String getExpensiveResourceName(){
        if (resource == null) {
            this.initializeExpensiveResource();     
        }
        return this.resource.getName();
    }   

    public CheapResource getCheapResource(){
        return this.cheap;
    }

    private initializeExpensiveResource(){
        // do expensive initialization of field "resource"
    }

}

public class Test{
    public static void main (String args[]){

        FooClass foo = new FooClass("some string");
        CheapResource cr = foo.getCheapResource();
        String s = foo.getExpensiveResourceName(); 
          // just now is the expensive resource initialized

    }
}
Licenciado em: CC-BY-SA com atribuição
scroll top