Πέμπτη 27 Ιανουαρίου 2022

Flyweight pattern

  • What problem does Flyweight pattern solve?



Suppose we need to create and log Vehicle objects with random locations, at regular intervals, for an extended period

If we just create "new Vehicle().." every time, we will definitely get and OutOfMemory exception



How are we going to approach this issue?

Consider that we only need new locations. The Vehicle object instantiation is the same every time.



  • How does Flyweight pattern solve this?


We use the Factory pattern to provide the same Vehicle object to the caller, and then we can just set the random locations, and log it

Thus, our memory will now handle only 2 objects (one Truck and one Car)


This VehicleFactory has a vehicles property that holds only one instance of each vehicle type


Finally we use this factory to replace our previous "new Car()..", "new Truck()..", and set location, and log





Facade pattern

  • What problem does Facade pattern solve?



Suppose a caller client needs to make a vacation booking through a vacation company, including:

- Flight
- Hotel
- Car rental 

The client should only need to send his dates to the company.

He must do himself the flight, car and hotel bookings, one-by-one.

So below code should be fixed:


  • How does Facade pattern solve this?



We simply create a VacationFacade class, that includes all actions required to book a holiday (flight, hotel and car)




And finally use it in our client part















Τετάρτη 26 Ιανουαρίου 2022

Decorator pattern

  • What problem does Decorator pattern solve?



Suppose we have a hierarchy of shape objects:





At some point we may need a Circle with a red border layout dynamically.

Is it correct to create another concrete class statically?




No, we would duplicate our code, for only one little adjustment of a red border.

In addition, we can't have an extra interface for our new requirement, because all Components will have to implement the red border.

We also want a dynamic change only. 




  • How does Decorator pattern solve this?



The decorator pattern allows you to alter behavior dynamically, without affecting other objects of the same type.


We create an extra concrete class that 
- implements Component
- takes our to-be-decorated object as a constructor argument
- has generic functionality (add red border) for all Component objects
- has sole responsibility to add a red border





Code:


Use:

Only circle2 with have a red border


Note that ComponentWithRedBorder delegates execution to the original Component object, after having decorated it.






 



Τρίτη 25 Ιανουαρίου 2022

Composite pattern

  • What problem does Composite pattern solve?



Suppose we have some classes, like:
- Manager
- SalesPerson
- SalesTeam

that have similar functionality of payExpenses()

How are we going to execute payExpenses() for all Managers, all SalesPersons and all SalesTeams?

Do we really need to call payExpenses() for each type of these 3 entities, like:
- manager.payExpenses()
- salesPerson.payExpenses()
- salesTeam.payExpenses()
?

No.
We could have only one payExpenses() to handle all these cases,
in order to
-  reduce code duplication 
-  improve code readability 
-  improve code extendability


  • How does Composite pattern solve this?


- We will just have one Payee interface's payExpenses() method to handle all cases
- All related entities will implement the same Payee interface


1. Create a Payee interface with one payExpenses() method




2. Manager, SalesPerson and SalesTeams will implement the same Payee interface

    public class Manager implements Payee {

      public void payExpenses(int amount) {
        // pay manager procedure...
      }

   }


3. In addition, SalesTeam will replace manager and salesPerson references with the new Payee interface type

Old SalesTeam:

New SalesTeam:

4. Finally, in our Main method we use the new structure, like:







Bridge Pattern

  • What problem does Bridge pattern solve?



Suppose we have a red Triangle, a red Square, and a red Circle shape

What if we want a yellow, green, purple etc. for each of above shapes?
Will we create a new class, like YellowCircleShape, PurpleCircleShape, etc.,  for each case?

This will lead to overpopulation of objects in a huge hierarchy, not manageable at all.

This may seem ok:


But not this one:







  • How does Bridge pattern solve this?


-Decouple Shapes and Colors
-Create a Color once, and re-use it in any Shape

1. Distinguish Shapes and Colors hierarchies



2. Color classes will have the sole responsibility of altering the color of the underlying Shape reference (using Graphics reference)



3. Shape classes will accept Colors in their constructors (Bridge)



4. Use final Shape classes, passing the Color as parameter:























Adapter pattern

  • What problem does Adapter pattern solve?



Suppose we have a common PriceCalculator interface for:

- CarPriceCalculator 
- TruckPriceCalculator 

in order to call printVehiclePrice() for both of them:




At some point, we may want to add an extra UKPriceCalculator, that doesn't/shouldn't belong (e.g. a third party calculator) to above hierarchy, and thus cannot implement PriceCalculator, and cannot call printVehiclePrice()




  • How does Adapter pattern solve this?


1. Create an Adapter class implementing PriceCalculator interface
2. Add a UKCarPriceCalculator class property


3. Override PriceCalculator's calculatePrice(), referring UKCarPriceCalculator methods


4. Finally, use the new Adapter class in main method