“Журналирование” или шаблон разработки “транзакций”? [закрытый]

8
задан Ricket 29 July 2010 в 16:28
поделиться

4 ответа

Лучший способ добиться желаемого - сделать объект и все его подобъекты неизменяемыми. Тогда два потока могут работать с ними без каких-либо конфликтов, и вам не нужно поддерживать две копии всего. Единственное, что потребует двух копий, - это вещи, которые действительно меняются, и они могут быть очень маленькими.

Предположим, что объект A состоит из объектов B и C. Объект B состоит из объектов D и E. А объект C состоит из объектов F и G. Таким образом, A, B и C являются только двумя указателями, а D , E, F и G - все, что они есть.

Сначала вы создаете свой начальный экземпляр и передаете его обоим потокам.

ThreadOne -> A1{ B1{ D1, E1 } C1{ F1, G1 } } 
ThreadTwo -> A1{ B1{ D1, E1 } C1{ F1, G1 } } 

Таким образом, оба потока указывают на один и тот же экземпляр, дополнительная память не используется, и нет проблем с потоками, потому что объекты никогда не меняются.

Теперь ThreadOne нужно изменить объект F. Для этого он просто создает новый F, новый C, содержащий его, и новый A, содержащий новый C. Исходные B, D, E и G являются без изменений и не требует копирования.

ThreadOne -> A2{ B1{ D1, E1 } C2{ F2, G1 } } 
ThreadTwo -> A1{ B1{ D1, E1 } C1{ F1, G1 } } 

Два потока совместно используют экземпляры B, D, E и G.

Теперь ThreadOne нужно изменить объект E.

ThreadOne -> A3{ B2{ D1, E2 } C2{ F2, G1 } } 
ThreadTwo -> A1{ B1{ D1, E1 } C1{ F1, G1 } } 

Теперь ThreadTwo нужна последняя версия, поэтому ThreadOne просто дает ему указатель на свой копировать.

ThreadOne -> A3{ B2{ D1, E2 } C2{ F2, G1 } } 
ThreadTwo -> A3{ B2{ D1, E2 } C2{ F2, G1 } } 

Поскольку объекты неизменяемы, нет опасности каких-либо проблем с потоками, и ThreadOne может сразу же вносить изменения, каждый раз создавая новый экземпляр только тех частей, которые были изменены, и их контейнеров.

ThreadOne -> A4{ B3{ D2, E2 } C2{ F2, G1 } } 
ThreadTwo -> A3{ B2{ D1, E2 } C2{ F2, G1 } } 

ThreadOne -> A5{ B3{ D2, E2 } C3{ F3, G1 } } 
ThreadTwo -> A3{ B2{ D1, E2 } C2{ F2, G1 } } 

Это быстро, эффективно с точки зрения памяти и потокобезопасно.

7
ответ дан 5 December 2019 в 17:33
поделиться

Вам нужен шаблон команд . Вы создаете объекты Command, которые выполняют и отменяют изменения и просто сохраняют некоторое базовое состояние, а затем воспроизводят любые команды, необходимые для приведения объекта в желаемое состояние.

1
ответ дан 5 December 2019 в 17:33
поделиться

То, что вы описываете, очень похоже на образец Memento . Однако вы указали, что не хотите сохранять все состояние объекта, поэтому этот шаблон может не работать для вас "из коробки".

Тем не менее, вы можете изменить его так, чтобы сувенир включал только дельты, а не полное состояние объекта. Это привело бы к меньшему объему памяти. Однако это также будет означать, что вы можете откатывать состояния только по порядку, поскольку их дельты будут зависеть друг от друга.

1
ответ дан 5 December 2019 в 17:33
поделиться

Вы можете объединить шаблоны Command и Memento. У вас могут быть конкретные команды, реализующие операции фиксации и отката, а также сувениры, которые сохранят состояние измененного объекта до фиксации.

1
ответ дан 5 December 2019 в 17:33
поделиться