Pergunta

Say Eu tenho uma classe que é feito para executar uma única função. Depois de realizar a função, pode ser destruída. Existe alguma razão para preferir uma dessas abordagens?

// Initialize arguments in constructor
MyClass myObject = new MyClass(arg1, arg2, arg3);
myObject.myMethod();

// Pass arguments to method
MyClass myObject = new MyClass();
myObject.myMethod(arg1, arg2, arg3);

// Pass arguments to static method
MyClass.myMethod(arg1, arg2, arg3);

Eu estava sendo intencionalmente vago sobre os detalhes, para tentar obter diretrizes para situações diferentes. Mas eu realmente não tem em mente funções de biblioteca simples como Math.random (). Estou pensando mais em classes que executam alguma específica, tarefa complexa, mas só exigem um método (público) para fazê-lo.

Foi útil?

Solução

Eu costumava classes de utilitários amor preenchidos com métodos estáticos. Eles fizeram uma grande consolidação dos métodos auxiliares que de outra forma se encontram ao redor causando redundância e manutenção inferno. Eles são muito fáceis de usar, não instanciação, nenhuma disposição, apenas fire'n'forget. Eu acho que esta foi a minha primeira tentativa inconsciente na criação de uma arquitetura orientada a serviços - lotes de serviços apátridas que apenas fez o seu trabalho e nada mais. Como um sistema cresce no entanto, dragões estar chegando.

Polimorfismo
Digamos que temos a UtilityClass.SomeMethod método que felizmente vibra junto. De repente, é preciso mudar a funcionalidade ligeiramente. A maioria das funcionalidades é a mesma, mas nós temos que mudar um par de peças, no entanto. Se não fosse um método estático, podemos fazer uma classe derivada e alterar o conteúdo do método, conforme necessário. Como é um método estático, não podemos. Claro, se nós só precisa adicionar funcionalidade antes ou após o método antigo, podemos criar uma nova classe e chamar o antigo dentro dele - mas isso é apenas bruto

.

Interface problemas
Os métodos estáticos não podem ser definidas através de interfaces por razões lógicas. E uma vez que não é possível substituir métodos estáticos, classes estáticas são inúteis quando precisamos passá-los em torno de sua interface. Isso nos torna incapazes de usar classes estáticas como parte de um padrão de estratégia. Podemos corrigir alguns problemas por passando delegados em vez de interfaces .

Teste
Este basicamente vai em conjunto com os problemas de interface acima mencionados. Como nossa capacidade de implementações intercambiando é muito limitado, nós também terá problemas substituindo o código de produção com código de teste. Mais uma vez, podemos envolvê-los, mas ele vai nos obrigar a mudar grandes partes do nosso código apenas para ser capaz de aceitar wrappers em vez dos objetos reais.

Fosters blobs
Como métodos estáticos são geralmente utilizados como métodos de utilitário e métodos utilitários geralmente têm finalidades diferentes, vamos rapidamente acabar com uma grande classe encheu-se com a funcionalidade não coerente - de preferência, cada classe deve ter um único propósito dentro do sistema. Eu prefiro ter um cinco vezes as classes, desde que seus propósitos são bem definidas.

Parâmetro fluência
Para começar, aquele pequeno método bonito e inocente estática pode ter um único parâmetro. Como funcionalidade cresce, um par de novos parâmetros são adicionados. Logo outros parâmetros são adicionados que são opcionais, por isso criamos sobrecargas do método (ou apenas adicionar valores padrão, em idiomas que os apoiam). Em pouco tempo, temos um método que leva 10 parâmetros. Apenas os três primeiros são realmente necessários, parâmetros 4-7 são opcionais. Mas se o parâmetro 6 é especificado, 7-9 são necessários para ser preenchido, bem ... Se tivéssemos criado uma classe com o único propósito de fazer o que este método estático fez, nós poderia resolver isso tomando os parâmetros necessários no construtor, e permitindo que o utilizador a valores opcionais conjunto através de propriedades, ou métodos para definir vários valores interdependentes ao mesmo tempo. Além disso, se um método tem crescido para essa quantidade de complexidade, necessidades com maior probabilidade de estar em sua própria classe de qualquer maneira.

consumidores exigentes para criar uma instância de aulas sem razão
Um dos mais argumentos comuns é, por demanda que os consumidores de nossa classe criar uma instância para chamar esse método único, ao não ter nenhum uso para a instância depois? Criando uma instância de uma classe é uma operação muito, muito barato na maioria das línguas, assim que a velocidade não é um problema. Adicionando uma linha extra de código para o consumidor é um baixo custo para lançar as bases de uma solução muito mais sustentável no futuro. E, finalmente, se você quer evitar a criação de instâncias, basta criar um WRA singletonpper de sua classe que permite a fácil reutilização - embora isso faz a exigência de que sua classe é apátrida. Se não for apátrida, você ainda pode criar métodos de mensagens publicitárias estáticas que lidam com tudo, enquanto ainda dando-lhe todos os benefícios a longo prazo. Finalmente, você também pode fazer uma classe que esconde a instanciação como se fosse um singleton: MyWrapper.Instance é uma propriedade que retorna apenas novas MyClass ();

Apenas um Sith ofertas em absolutos
Claro, há exceções a minha antipatia de métodos estáticos. classes de utilitários verdadeiros que não representam qualquer risco para o inchaço são excelentes casos de métodos estáticos - System.Convert como um exemplo. Se o seu projecto é um one-off sem requisitos de manutenção futura, a arquitetura geral realmente não é muito importante - estática ou não estática, realmente não importa -. Velocidade de desenvolvimento faz, no entanto

Padrões, normas, padrões!
Usando os métodos de instância não inibe-o de também usando métodos estáticos, e vice-versa. Enquanto há raciocínio por trás da diferenciação e é padronizado. Não há nada pior do que olhar sobre uma camada de negócios em expansão com diferentes métodos de execução.

Outras dicas

Eu prefiro a forma estática. Desde que a classe não está representando um objeto não faz sentido fazer uma instância do mesmo.

As classes que só existem para os seus métodos devem ser deixados estático.

Se não há nenhuma razão para ter uma instância da classe criada para executar a função, em seguida, usar a implementação estática. Por que fazer os consumidores desta classe criar uma instância quando não é necessário.

Se você não precisa salvar o Estado do objeto, então não há necessidade de instanciar-lo em primeiro lugar. Eu iria com o método estático único que você passar parâmetros para.

Eu também alertar contra uma classe gigante Utils que tem dezenas de métodos estáticos não relacionados. Isso pode ficar desorganizado e pesado em uma pressa. É melhor ter muitas classes, cada um com alguns métodos relacionados.

Eu diria que o formato Método estático seria a melhor opção. E eu gostaria de fazer a classe estática, bem como, de que maneira você não teria que se preocupar em criar acidentalmente uma instância da classe.

Eu realmente não sei qual é a situação aqui, mas eu olhava para colocá-lo como um método em uma das classes que arg1, arg2 ou arg3 pertencem - Se você pode semanticamente dizer que uma dessas classes possuiria o método.

Eu sugiro que é difícil de responder com base nas informações fornecidas.

Meu instinto é que se você está indo só para ter um método, e que você está indo jogar a classe imediatamente, em seguida, torná-lo uma classe estática que leva todos os parâmetros.

Claro, é difícil dizer exatamente por que você precisa para criar uma única classe apenas para este método. É o típico "class Utilities" situação como a maioria está assumindo? Ou implementar algum tipo de classe de regra, de que poderia haver mais no futuro.

Por exemplo, tem essa classe seja plugable. Então você gostaria de criar uma interface para seu método, e então você gostaria de ter todos os parâmetros passados ??para a interface, em vez de para o construtor, mas você não quer que ele seja estático.

Pode a sua classe ser feita estática?

Se assim for, então eu tinha que fazer isso uma classe 'Utilities' que eu iria colocar todas as minhas aulas de uma função em.

Se este método é apátrida e você não precisa passar por ai, então faz mais sentido para defini-lo como estático. Se você precisa fazer para passar o método ao redor, você pode considerar o uso de um delegar em vez de um de seus outras abordagens propostas.

Para aplicações simples e ajudantes internal, eu usaria um método estático. Para aplicações com componentes, estou amando a Managed extensibilidade Framework. Aqui está um trecho de um documento que eu estou escrevendo para descrever os padrões que você vai encontrar em toda a minha APIs.

  • Serviços
    • Definido por uma interface I[ServiceName]Service.
    • exportados e importados pelo tipo de interface.
    • A única implementação é fornecida pelo aplicativo host e consumida internamente e / ou por extensões.
    • Os métodos na interface de serviço são thread-safe.

Como um exemplo artificial:

public interface ISettingsService
{
    string ReadSetting(string name);

    void WriteSetting(string name, string value);
}

[Export]
public class ObjectRequiringSettings
{
    [Import]
    private ISettingsService SettingsService
    {
        get;
        set;
    }

    private void Foo()
    {
        if (SettingsService.ReadSetting("PerformFooAction") == bool.TrueString)
        {
            // whatever
        }
    }
}

Gostaria apenas de fazer tudo no construtor. como assim:

new MyClass(arg1, arg2, arg3);// the constructor does everything.

ou

MyClass my_object(arg1, arg2, arg3);

Uma questão mais importante a considerar é se o sistema seria funcionando em um ambiente multithread, e se seria thread-safe ter um método estático ou variáveis ??...

Você deve prestar atenção para o estado do sistema.

Você pode ser capaz de evitar a situação todos juntos. Tente refazer para que você obtenha arg1.myMethod1(arg2, arg3). arg1 de swap com qualquer arg2 ou arg3 se faz mais sentido.

Se você não tem controle sobre a classe de arg1, então decorá-lo:

class Arg1Decorator
    private final T1 arg1;
    public Arg1Decorator(T1 arg1) {
        this.arg1 = arg1;
    }
    public T myMethod(T2 arg2, T3 arg3) {
        ...
    }
 }

 arg1d = new Arg1Decorator(arg1)
 arg1d.myMethod(arg2, arg3)

O raciocínio é que, em OOP, dados e métodos de processamento que os dados pertencem juntos. Além disso, você obtém todas as vantagens que Mark mencionada.

Eu acho que, se as propriedades de sua classe ou a instância de classe não serão utilizados em construtores ou em seus métodos, os métodos não são sugeridos para ser concebido como padrão 'estática'. método estático deve ser sempre thinked em forma 'help'.

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