How to instantiate Strategy objects

Asked

Viewed 82 times

3

Consider the basic implementation of the standard Strategy.

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
  }

Doubt refers to its use, i.e., how to instantiate objects ConcreteStrategyA and ConcreteStrategyB?

I think of the following alternative: I create the object, in a control layer, for example, and transfer to the class Context, in which it invokes the method (polymorphic algoritmo()). But how to know the correct instantiating object? It would have to make a logic (use of if/else) to identify the correct object. But in this way, by making use of condition structures, I would be creating a problem that pattern Strategy seeks to resolve. Correct?

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

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

  • Did any of the answers solve your question? Do you think you can accept one of them? Check out the [tour] how to do this, if you haven’t already. You would help the community by identifying what was the best solution for you. You can accept only one of them. But you can vote on any question or answer you find useful on the entire site.

2 answers

4

I have a talk about the misuse of so-called Patterns design. The first problem is that people don’t know what such Dps are, and what they are for, where they can be applied, what can be called DP and what they are everywhere, where you don’t 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. Incidentally it may be one of the Dps.

If you don’t know how to apply the Strategy project pattern it’s because you don’t need it. At least not where you plan to use 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 that. 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 how to operate properly in that context.

With a question that is not very clear, you cannot know what is more appropriate. For a proper decision you need to understand all the requirements and know the entire organization of the application. DP cannot be used as a cake recipe without context. The question talks about different vehicle strategies, I don’t even know if it makes sense to use this PD in a case like this.

To tell you the truth, I doubt that’s the case for using Strategy there. It seems to me that there is a completely different object that should deal with the tariffs, it does not make any sense to try to stick the tariff inside the bike 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 even a vehicle and is misnamed.

Here comes the criticism I make of object orientation. If people cannot give the right names and classify the objects correctly, there is no methodology or paradigm that makes the software well written. Without a good understanding of ontology and taxonomy, you can’t 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 don’t guarantee these things that I’m putting here because the question isn’t clear. When you don’t have clarity of the problem to the point where you can’t describe the problem in Portuguese, it’s more complicated to write in Java or another language. All solutions have the potential to be wrong, using PD or not.

The other answer tells you how to use Strategy DP, but it doesn’t say this is the right thing to do and I hope you don’t think it is. This way violates the cohesion forcing a class to take care of things that don’t concern you.

Another conceptual error is to put Strategy as a temporary means of accomplishing something. This DP was created to create objects that will have the same strategy throughout their lifetime and not change according to the situation. Again, this might even be right if that’s not a vehicle but rather a completion of a vehicle’s stay, which is completely different from being a vehicle or even a stay.

Most of the problems we deal with are about composition and OOP has inheritance, polymorphism or grouping things into the same object, so OOP doesn’t work well in most cases that people think is the solution.

2

But in this way, by making use of condition 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 for a family of algorithms. The client does not care about the implementation of the interface as long as it is in agreement with the interface. In this sense, yes, Pattern Strategy seeks to avoid the need to choose an implementation directly in the class you want to call the algorithm.

However, eventually we have to inevitably make a decision on which implementation to instantiate. There it gets a little difficult to escape from ifs. In that case, I suggest two approaches:

  • use the Pattern Factory. It aims to isolate the process of creating objects. You can inform the type of vehicle and period and it returns the appropriate algorithm. You still end up with a sequence of if/else or case/switch, however, they are encapsulated within this 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();
  }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.