zagales / establo

Un espacio para aprovechar (o no) el tiempo siendo exentos del servicio militar.
1 stars 0 forks source link

Gilded Rose Refactoring Kata #9

Closed valentinboyanov closed 3 years ago

valentinboyanov commented 4 years ago
valentinboyanov commented 4 years ago

Extensión VSC para autocompletado y documentación oficial para ruby: https://marketplace.visualstudio.com/items?itemName=castwide.solargraph

valentinboyanov commented 4 years ago

Para la próxima sesión:

Enlaces interesantes que se han compartido durante la sesión:

valentinboyanov commented 4 years ago

Para la próxima sesión:

valentinboyanov commented 4 years ago

Cosas que han salido durante la sesión:

danicatalan commented 4 years ago

La segunda foto son las tres posibles formas de escribir un elsif en Ruby.

La primera solo para enseñar lo bonitos que son los colores de mi VSCode :)

j-plou commented 4 years ago

La primera solo para enseñar lo bonitos que son los colores de mi VSCode :)

... y los DEDAZOS que tienes en el monitor :)

valentinboyanov commented 4 years ago

Para "simplificar" el código actual, en la última sesión, planteamos dos posibles caminos:

Lo que propusimos fue dividirnos en dos equipos e intentar implementar los dos caminos en paralelo durante la primera hora, juntarnos otra vez todos para comentar las soluciones y ver qué simplifica el código y qué no de cada camino.

danicatalan commented 4 years ago

Use a consistent structure in your class definitions:

class Person
  # extend and include go first
  extend SomeModule
  include AnotherModule

  # inner classes
  CustomError = Class.new(StandardError)

  # constants are next
  SOME_CONSTANT = 20

  # afterwards we have attribute macros
  attr_reader :name

  # followed by other macros (if any)
  validates :name

  # public class methods are next in line
  def self.some_method
  end

  # initialization goes between class methods and other instance methods
  def initialize
  end

  # followed by other public instance methods
  def some_method
  end

  # protected and private methods are grouped near the end
  protected

  def some_protected_method
  end

  private

  def some_private_method
  end
end

Source: https://github.com/rubocop-hq/ruby-style-guide#consistent-classes

valentinboyanov commented 4 years ago

En la última sesión descartamos la idea de separarnos por equipos, nos parecio mejor pasar por los dos caminos todos juntos. Empezamos extrayendo updaters de items. Despues empezamos a identificar comportamientos comunes entre los updaters y decidimos empezar a generalizar de forma que el DefaultUpdater modelaba el caso general y el resto los casos particulares.

Lo que hemos empezado a hacer se parece bastante a Template method pattern:

Intent

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.

Applicability

The Template Method pattern should be used

  • to implement the invariant parts of an algorithm once and leave it up to subclasses to implement the behaviour that can vary.
  • when common behaviour among subclasses should be factored and localized in a common class to avoid code duplication. This is a good example of "refactoring to generalize" as described by Opdyke and Johnson [OJ93]. You first identify the differences in the existing code and then separate the differences into new operations. Finally, you replace the differing code with a template method that calls one of these new operations.
  • to control subclasses extensions. You can define a template method that calls "hook" operations (see Consequences) at specific points, thereby permitting extensions only at those points.

Consequences

Template methods are a fundamental technique for code reuse. They areparticularly important in class libraries, because they are the means for factoring out common behavior in library classes.

Template methods lead to an inverted control structure that's sometimes referred to as "the Hollywood principle," that is, "Don'tcall us, we'll call you" [Swe85]. This refers to how a parent class calls the operations of a subclass and not the other way around.

Template methods call the following kinds of operations:

  • concrete operations (either on the ConcreteClass or on client classes);
  • concrete AbstractClass operations (i.e., operations that are generally useful to subclasses);
  • primitive operations (i.e., abstract operations);
  • factory methods (see Factory Method (121)); and
  • hook operations, which provide default behaviour that subclasses can extend if necessary. A hook operation often does nothing by default.

It's important for template methods to specify which operations are hooks (maybe overridden) and which are abstract operations(must be overridden). To reuse an abstract class effectively, subclass writers must understand which operations are designed for overriding.

-- Design Patterns: Elements of Reusable Object-Oriented Software

Para la siguiente sesión propongo itentar definir de forma abstracta el algoritmo de actualizar la ¿calidad/estado/etc? del item, identificar las concrete operations, primitive operations, hook operations y ver si se simplifica o complica la cosa :) Tambien ver qué impacto puede generar esto en los tests, ya que la última vez nos dimos cuenta que tambien parecian confusos cuando tiramos de ellos para entender el comportamiento del código.

valentinboyanov commented 3 years ago

Estamos con otra kata, cerramos issue por ahora.