Clase para exponer información con propiedades de la computadora (GETTERS) -- swift camp codereview Relacionados El problema

Class for exposing information with computer properties (getters)


2
vote

problema

Español

Necesito algunos consejos en mi estructura de código. He leído que los colonos y los consignos rompen uno de los directores, encapsulación de la OOP, y que debemos evitarlos si es posible, pero no puedo pensar en ninguna otra forma de exponer información que no sea Getters.

Tengo una clase que calcula el precio, los ahorros y los impuestos basados ​​en tres insumos del usuario a través del inicializador (primer impacto, descuento y fiscal).

Estoy usando tres propiedades de computadora para exponer los resultados, ¿se considera algo malo? Si es así, ¿por qué y cómo puedo mejorar mi código?

Además de lo que describí por encima de la clase también tiene la capacidad de agregar todos los elementos en una matriz, suponiendo que las instancias de la cálculadora se colocaron en una matriz.

de nuevo, estoy más preocupado por la estructura de mi código. Se apreciará cualquier consejo.

  class CalculatorBrain {            private var taxRate:Double = 0           private var discount:Double = 0           private var initialPrice:Double = 0            func setInitialValues(initialPrice:Double, discount:Double, taxRate:Double){               self.taxRate = taxRate               self.discount = discount               self.initialPrice = initialPrice           }            private func salePrice()->Double{               return initialPrice - savings           }            var price:Double{               get{                   return salePrice() + taxes               }           }            var savings:Double{               get{                   return initialPrice * discount / 100               }           }            var taxes:Double{               get{                   return salePrice() * taxRate / 100               }           }            internal func grandTotals(list:Array<Item>)->(grandPrice:Double, grandSavings:Double, grandTaxes:Double){               var grandPrice:Double = 0               var grandSavings:Double = 0               var grandTaxes:Double = 0                for i in 0..<list.count {                   grandPrice = grandPrice + Double(list[i].totalPrice)                   grandSavings =  grandSavings + Double(list[i].savings)                   grandTaxes = grandTaxes + Double(list[i].taxes)               }               return (grandPrice, grandSavings, grandTaxes)           }       }    
Original en ingles

I need some advice on my code structure. I have read that setters and getters break one of the OOP principals, encapsulation, and that we should avoid them if possible but I cannot think of any other way to expose info other than getters.

I have a class which calculates price, savings and taxes based three inputs from the user through the initializer (initialPrice, discount and taxRate).

I'm using three computer properties to exposed the results, is this considered a bad thing? If yes, why and how can I improve my code?

Besides what I described above the class also has the ability to add all of the items in an array, assuming the instances of the CalculatorBrain were placed in an array.

Again, I'm more concern about the structure of my code. Any advice will be appreciated.

class CalculatorBrain {            private var taxRate:Double = 0           private var discount:Double = 0           private var initialPrice:Double = 0            func setInitialValues(initialPrice:Double, discount:Double, taxRate:Double){               self.taxRate = taxRate               self.discount = discount               self.initialPrice = initialPrice           }            private func salePrice()->Double{               return initialPrice - savings           }            var price:Double{               get{                   return salePrice() + taxes               }           }            var savings:Double{               get{                   return initialPrice * discount / 100               }           }            var taxes:Double{               get{                   return salePrice() * taxRate / 100               }           }            internal func grandTotals(list:Array<Item>)->(grandPrice:Double, grandSavings:Double, grandTaxes:Double){               var grandPrice:Double = 0               var grandSavings:Double = 0               var grandTaxes:Double = 0                for i in 0..<list.count {                   grandPrice = grandPrice + Double(list[i].totalPrice)                   grandSavings =  grandSavings + Double(list[i].savings)                   grandTaxes = grandTaxes + Double(list[i].taxes)               }               return (grandPrice, grandSavings, grandTaxes)           }       }  
  
     
     

Lista de respuestas

2
 
vote
vote
La mejor respuesta
 

¿Establece los valores iniciales?

  private var taxRate:Double = 0   private var discount:Double = 0   private var initialPrice:Double = 0    func setInitialValues(initialPrice:Double, discount:Double, taxRate:Double){       self.taxRate = taxRate       self.discount = discount       self.initialPrice = initialPrice   }     

No me importa esto en absoluto.

Primero, no veo una buena razón para estas tres propiedades para ser necesariamente private . ¿Por qué el usuario debería tener que adivinar qué tienen sus propiedades a?

Además, no está protegiendo estos valores de ser reiniciado. El usuario simplemente tiene que llamar setInitialValues de nuevo. El nombre del método puede ser un intento de sugerencia para que sea el uso incorrecto de la clase, pero mi mantra es deja que el compilador haga lo más posible para nosotros.

Debemos exponer estas propiedades al usuario. No debemos permitir que el usuario modifique estas propiedades después de la inicialización. Deberíamos escribir un método 99887766655443333 .

  let taxRate: Double let discount: Double let basePrice: Double  init(taxRate: Double = 0, discount: Double = 0, basePrice: Double = 0) {     self.taxRate = taxRate     self.discount = discount     self.basePrice = basePrice }   

¿Por qué salePrice() una función?

Usted ha implementado básicamente todo lo demás como una propiedad computarizada, solo de lectura. ¿Por qué no se puede salePrice también ser una propiedad computada, solo lectura? Si desea que sea privado, está bien si eso tiene sentido para su clase, pero aún puede ser una propiedad computada.

  var salePrice: Double {     return basePrice - savings }   

Además, tenga en cuenta lo que he hecho aquí. El get { } se omite. Las propiedades computadas que simplemente devuelven un valor pueden omitir el 9988776665544339 y solo son de lectura implícitamente. Se supone que cualquier código es para el private0 Si ha omitido el 99887776655443311 & amp; private2 Palabras clave.


private3 es el nivel de acceso predeterminado.

Usted ha marcado algunas cosas como private4 . Ha omitido un especificador de acceso en la mayoría de las cosas, y luego se especifica su método general general como private5 . Marcado private6 es el mismo que omitir un especificador de acceso. Debe eliminar este private7 palabra clave aquí, o la use constantemente con todas las demás propiedades. Ninguno de sus miembros es private8 en su implementación actual.


Acerca de ese private9 MÉTODO ...

Este método casi parece fuera de lugar si no estaba por el hecho de que la clase se llama setInitialValues0 . Pero no depende de ningún estado, por lo que probablemente debería ser un método 998877766555443321 .

su Loop está lejos de óptimo . Pero, ni siquiera necesitamos un bucle. Podemos usar setInitialValues2 .

  setInitialValues3  

Pero ... podría evitar devolver una tupla. ¿Por qué no solo hacer una estructura?

  setInitialValues4  

y ahora en lugar de un método que se siente como si está en un lugar extraño, solo agregamos un 9988777665555443325 :

  setInitialValues6  
 

Set Initial Values?

private var taxRate:Double = 0   private var discount:Double = 0   private var initialPrice:Double = 0    func setInitialValues(initialPrice:Double, discount:Double, taxRate:Double){       self.taxRate = taxRate       self.discount = discount       self.initialPrice = initialPrice   }   

I don't care for this at all.

First, I don't see a good reason for these three properties to necessarily be private. Why should the user have to guess what they've set their properties to?

Further more, you're not protecting these values from being reset. The user simply has to call setInitialValues again. The method name may be an attempted hint at that being the incorrect use of the class, but my mantra is let the compiler do as much for us as possible.

We should expose these properties to the user. We should not allow the user to modify these properties after initialization. We should write an init method.

let taxRate: Double let discount: Double let basePrice: Double  init(taxRate: Double = 0, discount: Double = 0, basePrice: Double = 0) {     self.taxRate = taxRate     self.discount = discount     self.basePrice = basePrice } 

Why is salePrice() a function?

You have implemented basically everything else as a computed, read-only property. Why can't salePrice also be a computed, read-only property? If you want it to be private, that's fine if that makes sense for your class, but it can still be a computed property.

var salePrice: Double {     return basePrice - savings } 

Also, note what I've done here. The get { } is omitted. Computed properties that just return a value can omit the get and are implicitly read-only. Any code is assumed to be for the get if you have omitted the get & set keywords.


internal is the default access level.

You have marked some things as private. You have omitted an access specifier on most things, and then your grand total method is specified as internal. Marking internal is the same as omitting an access specifier. You should drop this internal keyword here, or consistently use it with all the other properties. None of your members are public in your current implementation.


About that grandTotals method...

This method almost seems out of place if it weren't for the fact that the class is called CalculatorBrain. But it doesn't depend on any state, so it should probably be a static method.

Your loop is far from optimal. But, we don't even need a loop. We can use reduce.

return list.reduce((0,0,0)) {      return (         $0.totalPrice + $1.totalPrice,         $0.savings + $1.savings,         $0.taxes + $1.taxes     ) } 

But... I might avoid returning a tuple. Why not just make a struct?

struct GrandTotal {     let price: Double     let savings: Double     let taxes: Double } 

And now instead of a method that feels like it's in a weird place, we just add an appropriate init:

struct GrandTotal {     let price: Double     let savings: Double     let taxes: Double      init(list: [Item]) {         let totals = list.reduce((0,0,0)) {              return (                 $0.totalPrice + $1.totalPrice,                 $0.savings + $1.savings,                 $0.taxes + $1.taxes             )         }                  price = totals.0         savings = totals.1         taxes = totals.2     } } 
 
 
       
       

Relacionados problema

6  A * Implementación genérica en SWIFT  ( A generic implementation in swift ) 
My First Code Review Post. Estoy a la altura de una Implementación genérica del algoritmo de búsqueda A * en SWIFT (por ahora, es una sola implementación ...

4  Función de expresión del interruptor  ( Switch expression function ) 
Hice un montón de funciones y una enumeración, que juntos me permiten escribir algo como una expresión de conmutación. No es tan poderoso como las declaracion...

0  Estructuración eficiente de los datos con enfoque orientado al protocolo en SWIFT  ( Efficiently structuring data with protocol oriented approach in swift ) 
Necesito integrar algunas llamadas de API del servidor en las que es probable que obtenga una respuesta como: + Response 200 (application/json) + Body ...

2  Swift HackerRank faltante Números Challenge  ( Swift hackerrank missing numbers challenge ) 
Estoy intentando resolverlo el desafío de "números faltantes" en Hackerrank donde Me encargo de encontrar elementos que faltan comparando dos matrices. {...

2  Modelo para hechos matemáticos  ( Model for math facts ) 
He escrito un modelo para una aplicación que genera hechos de matemáticas Los niños tienen que resolver evaluando la operación y la dificultad que le pasa a l...

2  Formateo de un precio en SWIFT usando una extensión vs. una clase  ( Formatting a price in swift using an extension vs a class ) 
Tengo un precio como un Double , que debería formatearlo como un String . ¿Debo usar una extensión en lugar de clase clásica para encapsular "Formater", "...

3  Aplanar para obtener todos los controles infantiles de cierto tipo en una UIView  ( Flatten to get all child controls of certain type in a uiview ) 
extension Array { func flatten<TResult>(transform: (T) -> TResult?, childArray: (T) -> [T]) -> [TResult] { var result = [TResult]() for ...

10  Objeto de portafolio hecho de clases de activos y valores  ( Portfolio object made of asset classes and securities ) 
Estoy aprendiendo la programación rápida y orientada a objetos. Soy nuevo para diseñar patrones y programación orientada al protocolo. En mi código de prueb...

2  Cargando imágenes en el fondo para una vista de tabla  ( Loading images in the background for a table view ) 
Tengo fetchData2 MÉTODO QUE LLENA MI imagesArray : func fetchData(){ let imageQuery = PFUser.query() imageQuery?.whereKey("username", contained...

5  Mostrando una cierta pantalla dependiendo de un estado particular  ( Showing a certain screen depending on a particular status ) 
En esta aplicación de iOS en la que estoy trabajando, hay dos pantallas de aterrizaje que se muestran al usuario dependiendo de un estado en particular. Las p...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos