How much can you prevent existing code from being modified when using design patterns?

I take the class of design patterns at school and read some chapters of design patterns of the head of the first. What I would like to know depends on the extent to which design patterns prevent rewriting of existing code.

Take, for example, the Duck and FlyBehavior . In my public static void main(String[] args) following code:

 Duck mallard = new MallardDuck(new FlyWithWings()); 

Am I saying correctly that you need to change your main() method if you want to add a new strategy? So you are modifying existing code, right? I specifically refer to the part that mentions a particular strategy class: new FlyWithWings().

If you have implemented the factory method template in your code, you can FlyWithWings specific class ( FlyWithWings ) at all:

 public FlyBehavior returnBehavior(FlyBehaviorFactory factory, String behaviorType) { return factory.getFlyBehavior(behaviorType); } 

And thus enter the following line of code:

 Duck mallard = new MallardDuck(returnBehavior(flyFactory, "wings")); 

Thus, a certain part of your program should not know what to use FlyBehaviorFactory. However, your main() method will still have to specify certain parameters in the returnBehavior method to find out which factory will create which strategy. So, can I say that you still have to change main() if I add a new FlyBehavior class and want to add it as a parameter to returnBehavior() ?

Is it possible to improve this situation further?

+5
source share
2 answers

In the current example, you hardcode the parameters passed to your factory, and thus decide the behavior at compile time .

 Duck mallard = new MallardDuck(returnBehavior(flyFactory, "wings")); 

This can be changed for the runtime specific behavior plugin instead of compile time :

 Duck mallard = new MallardDuck(returnBehavior(flyFactory, args[0])); 

With the above change, you will never have to change your main method. Your factory can be written in such a way that it throws a exception when the behavior obtained at runtime is not available:

 if(behaviorType.equals("wings") { //...create FlyWithWings } else{ //throw an appropriate exception indicating that the behavior does not exist } 

In this case, it is inevitable to change the code if a new behavior is introduced. Although this change will be in one place and as far as possible in your application, i.e. Your factory , which is the whole factory item first. In addition, when you create a new FlyBehavior , you do this by extending an existing class. This is built into the open-closed principle

0
source

What you do here is an injection of addiction, you inject FlyBehaviour into Duck. Sometimes, when you use dependency injection, you can have a chain of injections. For example, if you want a speed strategy to be introduced in FlyBehaviour, you might have something like this.

 Duck mallard = new MallardDuck(new FlyWithWings(new FastSpeed())); 

It would be nice to have a core and any other class that Duck uses to know about all of these classes and change each one of them every time. A better solution would be to use a dependency injection container, which is responsible for creating each of these classes. Then basically you can just call something like this

 Duck mallard = (Duck) Container.get('Duck'); 

The container is responsible for creating all the instances needed for the injection. Therefore, in order to answer your question, you will need to change your code if you want a new strategy, but at least in this way it will be only in one place, and not in the whole code, which can be a large number of files.

0
source

All Articles