Dobre praktyki programistyczne

Pierwsze wywołanie metody

07.07.2011

Zdarza się, że podczas pierwszego wywołania metody potrzebne jest wykonanie innej czynności, niż w pozostałych wywołaniach. Załóżmy, że nie chcemy w to angażować klienta. Można to zrobić w standardowy sposób, używając funkcji if/else i zmiennej boolean wskazującej czy uruchomić pierwszą akcję.

Istnieje jednak inne rozwiązanie. Wywodzimy klasę pochodną po klasie wykonującej standardową operację. Przysłaniamy wybraną metodę i wstawiamy tam kod, który ma się wykonać jako pierwszy. Na koniec należy jeszcze dodać instrukcję podmieniający obiekt polecenia na standardowy.

Diagram klas First Action

Klasa Facade powoduje, że klient nie widzi żadnych zmian. Zawiera ona polecenie Action, które jest zainicjowane jako FirstAction.

Facade   
  1. public class Facade {
  2. private Action action = new FirstAction(this);
  3.  
  4. //Method called by client
  5. public void callAction() {
  6. action.execute();
  7. }
  8.  
  9. //Used by FirstAction to set the standard Action object
  10. void setAction(Action action) {
  11. this.action = action;
  12. }
  13. }

FirstAction wykonuje pierwszą akcję i ustawią standardową akcję dla następnych wywołań. Dzięki temu, że FirstAction dziedziczy po Action nie ma problemu w podmianie obiektów.

  1. class FirstAction extends Action {
  2. private final Facade facade;
  3.  
  4. public FirstAction(Facade facade) {
  5. this.facade = facade;
  6. }
  7.  
  8. public void execute() {
  9. System.out.println("Start counting"); //do first action
  10. facade.setAction(new Action()); //set standard action for next executions
  11. }
  12. }

Action wykonuje pożądaną czynność, w tym przykładzie jest to wypisanie kolejnych liczb naturalnych.

Action   
  1. class Action {
  2. private int i = 1;
  3.  
  4. public void execute() {
  5. System.out.println(i++);
  6. }
  7. }

Kod testujący działanie tego wzorca projektowego:

Main   
  1. public static void main(String[] args) {
  2. Facade f = new Facade();
  3. for (int i = 0; i < 4; i++) {
  4. f.callAction();
  5. }
  6. }

Może to być dobre rozwiązanie, jeśli kodu wykonywanego w akcjach będzie na tyle dużo, że tworzenie nowych klas będzie uzasadnione. W najprostszych przypadkach łatwiej będzie zaimplementować poniższy kod:

Standard   
  1. public class Standard {
  2. private boolean first = true;
  3. private int i = 1;
  4.  
  5. public Standard() {
  6. }
  7.  
  8. public void execute() {
  9. if (first) {
  10. System.out.println("Start counting");
  11. first = false;
  12. } else {
  13. System.out.println(i++);
  14. }
  15. }
  16.  
  17. //Client's code
  18. public static void main(String[] args) {
  19. Standard standard = new Standard();
  20. for (int i = 0; i < 4; i++) {
  21. standard.execute();
  22. }
  23. }
  24. }

Pobierz cały kod FirstAction.zip.

Leave a Response