How to instantiate Strategy objects

1

Consider the basic implementation of the Strategy pattern.

public class Context{
  private Strategy strategy;
}

public interface Strategy{
  void algoritmo();
}

public class ConcreteStrategyA implements Strategy{
  void algoritmo(){
    // algoritmo A
  }
}

public class ConcreteStrategyB implements Strategy{
  void algoritmo(){
    // algoritmo B
  }

The question refers to its use, that is, how to instantiate objects ConcreteStrategyA and ConcreteStrategyB ?

I think of the following alternatives: I create the object, in a control layer, for example, and refer to the Context class, in which it invokes the method ( algoritmo() polymorph). But how to know which object to instantiate correctly? You would have to do a logic (use if / else ) to identify the correct object. But in this way, making use of conditional structures, I would be creating a problem that the Strategy pattern seeks to solve. Correct?

To make it clear, suppose the following scenario: I have a class CalculadoraDeTarifas ( Context ), it receives the type of vehicle (car, motorcycle, etc) and a period of time. Suppose I have a Strategy TarifaStrategy which is the interface for DiariaMoto , DiariaCarro , PorHoraMoto , PorHoraCarro , MensalidadeMoto , MensalidadeCarro . >

Consider now that I need to pass a motorcycle for a period of 15 hours. In this case, as one of the rules is that, when the period is more than 12 hours a "Daily" is charged for motorcycle. This calculation should be in algoritmo() of DiariaMoto , correct? If so, how do you get it to run?

    
asked by anonymous 14.12.2018 / 16:12

2 answers

3

I have a talk that talks about the misuse of so-called design patterns . The first problem is that people do not know what they are just such DPs, and who they serve, can be applied, what can be called PD and that they are everywhere, as far as you do not see them. The second problem is that people study them, learn the solution and then look for a problem to apply it. This is wrong, you must have a problem and find the best solution for it. You may happen to be one of the DPs.

If you do not know how to apply the Strategy project pattern, you do not need it. At least not where you plan on using it. If it is suitable its use is natural and does not need selectors, you create an object according to a demand and in it passes the strategy to be used, the standard is just this. Depending on the context of the application will be a different strategy. Eventually one arrives in this context with a if or switch , but this is tangential and secondary, it is not what defines the strategy to be used but rather how to operate properly in that context.

With a question not very clear you can not know what is most appropriate. For an appropriate decision you need to understand all the requirements and know the entire organization of the application. DP can not be used as a cake recipe without context. The question is about different vehicle strategies, I do not even know if it makes sense to use this DP in a case like this.

To tell you the truth, I doubt that is the case of using Strategy there. It seems to me that there is a completely different object that must deal with the tariffs, it makes no sense to try to insert the tariff inside the motorcycle or car. There is a relationship between the fare and the vehicle and the time used, but it is not the same object, a fare is a property of a vehicle, unless the specific class of the vehicle is not even a vehicle and is poorly named. p>

Here comes the criticism I make of object-orientation. If people can not give certain names and classify objects correctly, there is no methodology or paradigm that makes the software well written. Without good understanding of ontology and taxonomy you can not program OO. This code seems to fail at these points, so any penduricalho that tries to put in the code is already wrong because it is using a wrong base.

I do not guarantee these things that I am putting here because the question is not clear. When the problem is not clear to the point of not being able to describe the problem in Portuguese it is more complicated to write in Java or another language. All solutions have the potential to be wrong, using DP or not.

The other answer says how to use Strategy DP, but does not say that this is the right thing to do and hope you do not think it is. This form violates cohesion forcing a class to take care of things that do not concern you.

Another conceptual error is putting Strategy as a temporary means of doing something. This DP was created to create objects that will have the same strategy throughout their life time and not change according to the situation. Again, this could even be the case if it is not a vehicle but a completion of a vehicle, which is completely different from being a vehicle or even a stay.

Most of the problems we deal with are composition and OOP has inheritance, polymorphism, or grouping things on the same object, so OOP does not work well in most cases that people think it is the solution.

    
17.12.2018 / 16:42
2
  

But in this way, making use of conditional structures, I would be creating a problem that the Strategy pattern seeks to solve. Correct?

Yes and no.

The use of pattern strategy is to provide an interface to a family of algorithms. The client does not care about implementing the interface as long as it conforms to the interface. In this sense, yes, the strategy pattern tries to avoid the need to choose an implementation directly in the class that wants to call the algorithm.

However, we eventually inevitably have to make a decision about which implementation to instantiate. It's a little difficult to escape from ifs . In this case, I suggest two approaches:

  • use the pattern factory . It aims to isolate the process of creating objects. You can enter the type of vehicle and period and it returns you the appropriate algorithm. You still end up with a sequence of if/else or case/switch , however, they are encapsulated within that class.
  • If your algorithm choice condition is a class, you can put a method that instantiates the proper implementation of the algorithm for that class.
public interface ICalculoTarifa {
  void calcularTarifa();
}

public interface CalculoTarifaCarro implements ICalculoTarifa {
  public void calcularTarifa(){ 
    //implmentação
  }
}

public interface CalculoTarifaMoto implements ICalculoTarifa {
  public void calcularTarifa(){ 
    //implmentação
  }
}

public interface IVeiculo {
  IAlgoritmo getCalculoTarifa();
}

public interface Carro implements IVeiculo {
  public IAlgoritmo getCalculoTarifa(){
    return new CalculoTarifaCarro();
  }
}

public interface Moto implements IVeiculo {
  public IAlgoritmo getCalculoTarifa(){
    return new CalculoTarifaMoto();
  }
}
    
14.12.2018 / 17:51