22
February

Паттерн Memento (Память)

Posted in: Паттерны проектирования |

Поведенческий паттерн проектирования (behavioral pattern) Память нужен для хранения определенного состояния объекта. При сохранении не должна нарушаться парадигма ООП инкапсуляция. С другой стороны, должна присутствовать возможность возврата к предыдущему состоянию.
Ну, довольно сухих слов. Перейдем к практическому примеру паттерна Memento на Java.

Memento может понадобиться при создании preview для некоторой формы.
Пускай некоторый Bean-класс служит для хранения информации об интернет сайте. После регистрации пользователь может поменять только описание сайта и категорию, к которой относится данный ресурс.

public class SiteDescrBean {
    private long id;
    private String name;
    private String theURL;
    private String description;
    private int category;

    /* setters and getters
       are really boring methods :) */

    private Memento undo;

    private class Memento {
        String siteDescr;
        int siteCateg;

        Memento(String descr, int category) {
            siteDescr = descr;
            siteCateg = category;
        }

        String getDescr() {
            return siteDescr;
        }

        int getCateg() {
            return siteCateg;
        }
    }

    public void preview() {
        // ...
        undo = new Memento(description, category);
        // ...
    }

    public void undoChanges() {
        description = undo.getDescr();
        category = undo.getCateg();
        // ...
    }
}

Метод preview, помимо создания экземпляра класса Memento, может содержать код для считывания данных из веб-интерфейса (или GUI) и отображения измененных данных. С помощью метода undoChanges можно вернуть предыдущее состояние объекта SiteDescrBean.

Схожую технику можно использовать при написании текстового редактора. Только поле undo (или как там вы его назовете) лучше описать как массив или список, если вы конечно не хотите создать аналог notepad.

Паттерн Memento полезен в таких случаях:

  • необходим функционал undo/redo;
  • при транзакциях (базы данных);
  • сохранение информации для последующего использования;
  • получение информации о состоянии объекта без нарушения инкапсуляции.

Все.

2 Comments »

RSS feed for comments on this post. TrackBack URI



exgorth
March 23, 2007 #

Здорово! Красота.

Entry_N3
May 20, 2007 #

В книге Мугала и Расмуссена по подготовке к сдаче сертификационного экзмена на scjp в главе 7. “Вложенные классы и интерфейсы” этот паттерн (этот ли? :) ) приводится как один из вариантов использования локальных классов с проверкой диагностического утверждения

Там такой интересный пример:
class Account {
//баланс

void deposit(final int ){
class Auditor {
//сохранение баланса
boolean check(){assert (-)==;
}
//создание класса Auditor (сохранение данных)
//выполнение транзакции (увеличиваем счет)
//вызов у класса Auditor метод check()
}

… main(…){
Account ac = new Account();
ac.deposit(250);
}
}

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>