Um único objeto deve ser preferido em relação a várias variáveis?

8

Foi muito difícil colocar o que eu quis dizer em um título, mas é fácil colocar no código.

C ++

É isto

int offset_x = 10;
int offset_y = 40;
...
element.move(offset_x, offset_y);

Para ser preferido sobre isso?

Vector<int> offset(10, 40);
...
element.move(offset.x, offset.y);

(Observe que Vector não é como std::vector, é um vetor 2D. Esta classe tem muitos métodos que não preciso aqui, como normalize()e scale(). Devo ter uma Pointclasse mais básica para isso?)

Javascript

É isto

var offsetX = 10;
var offsetY = 40;
...
element.move(offsetX, offsetY);

Para ser preferido sobre isso?

var offset = {x: 10, y: 40};
...
element.move(offset.x, offset.y);
futlib
fonte

Respostas:

12

Eu "herdei" muito código legado usando sua primeira variante, e também escrevi muito código usando as classes Point2De Point3D(em geral, o mesmo que você Vector<int>é). A primeira variante sempre leva a funções com muitos parâmetros e muitas construções repetidas, nas quais a simples adição de vetor ou multiplicação escalar é repetida várias vezes em várias linhas de código.

O uso de classes de pontos ou vetores 2D, no entanto, especialmente quando você precisa de muitas operações de vetores, torna o código muito mais limpo, conciso, melhor legível e fácil de manter. Se você deve usar uma existente Vector<int>ou escrever sua própria Pointclasse, é impossível dizer sem saber mais sobre os detalhes do seu código, mas, em geral, se uma classe existente sofre sua necessidade, por que não reutilizá-la? Os métodos adicionais que você não precisa, típicos, não machucam. Mas não usar nenhuma classe de ponto / vetor 2D é quase sempre que a decisão errada. E no seu exemplo acima: se você tem influência sobre a element.movefunção, IMHO é melhor projetá-la de uma maneira que você possa chamar em element.move(offset)vez de element.move(offset_x, offset_y).

Por exemplo, digamos que você precise de uma matriz de coordenadas de ponto e use um a std::vector. No primeiro caso, você precisará de duas std::vector<int> variáveis, precisará garantir que esses dois vetores estejam "sincronizados" e que todos os novos elementos sejam adicionados, encontrem elementos existentes e passem por esses elementos, necessitando de duas linhas de código. de um quando você optou por usar um std::vector<Point2D>.

Doc Brown
fonte
3

Para dar uma resposta mais geral, as variáveis ​​devem ser agrupadas em um objeto quando faz sentido lógico fazê-lo.

  • As variáveis ​​são aspectos ou propriedades diferentes de uma "coisa"?
  • Eles sempre pertencem um ao outro?
  • Eles serão usados ​​o suficiente para justificar qualquer trabalho extra que possa estar envolvido na criação de um objeto?

No seu caso, eu diria que seu código melhora claramente quando você agrupa as variáveis.

Porém, se as variáveis ​​forem agrupadas em um objeto que não é bem pensado, você poderá ficar preso a um design pesado que é pior do que usar variáveis ​​normais.

Por outro lado, é possível projetar em excesso: gastar muito tempo pensando e construindo a estrutura orientada a objetos "perfeita", a ponto de impedir que você realmente faça as coisas.


fonte
1

Na verdade, acho que a melhor maneira é fazer isso:

Vector<int> offset(10, 40);
element.moveBy(offset);

Esse código abstrai a dimensionalidade de seus vetores, e a mesma linha de código ( element.moveBy(offset)) funcionará inalterada se você alterar seus vetores para 3D, ou duplicar ou mesmo coordenadas polares, desde que seus tipos implementem as operações necessárias corretamente.

Por exemplo, considere o seguinte código:

Vec wallBounce(Obj& o, cont Wall& w) {
    assert(isUnit(w.normal));
    Vec perp = dot(w.normal, o.velocity) * w.normal;
    o.velocity -= 2 * perp;
}

Qualquer pessoa com uma pista matemática de vetor suficiente entenderá o que acontece aqui; Além disso, a função é curta, ao ponto. Você não pode ver o que Vecé digitado, mas isso geralmente não é muito interessante e também trivial para procurar; a clareza e brevidade do código mais do que compensam isso. Afinal, a codificação consiste em fazer abstrações, e abstrair grupos de escalares em vetores é uma abstração muito poderosa. Para chutes, tente implementar a função acima sem fazer essas abstrações, para vetores 2D, vetores 3D e escalares.

tdammers
fonte