
use std::any::Any;
//Shape is Prototype
trait Shape {
fn clone(&self) -> Box<dyn Shape>;
fn as_any(&self) -> &dyn Any;
}
//Square is ConcretePrototype
#[derive(Debug)]
struct Square {
line_count: i32
}
impl Shape for Square {
fn clone(&self) -> Box<dyn Shape> {
Box::from(Square {
line_count: self.line_count
})
}
fn as_any(&self) -> &dyn Any { self }
}
//ShapeMaker contains a Shape
struct ShapeMaker {
shape: Box<dyn Shape>
}
//MakeShape creates a copy of the Shape
impl ShapeMaker {
fn make_shape(&self) -> Box<dyn Shape> {
Box::from(self.shape.clone())
}
}
//Client
let square = Square{ line_count: 4 };
let maker = ShapeMaker{
shape: Box::from(square) };
let square1 = maker.make_shape();
let square2 = maker.make_shape();
println!("square1 is {:?}", square1.as_any()
.downcast_ref::<Square>().unwrap());
println!("square2 is {:?}", square2.as_any()
.downcast_ref::<Square>());
Описывает виды создаваемых объектов с помощью прототипа и создает новые объекты путем его копирования.Read moreЗадача. В графическом редакторе есть палитра готовых фигур, и у каждой свои цвет, размер и рамка. Когда пользователь перетаскивает фигуру на страницу, программа должна сделать точно такую же новую фигуру. Если код пользуется конструктором, ему приходится знать точный класс и вручную копировать каждую настройку. Тогда каждый новый вид фигуры меняет этот код. Идея. Прототип - это готовый объект, который умеет себя копировать. У него один метод копирования, часто он называется clone. Клиент держит прототип и просит у него копии. Конкретный класс клиент не называет и не знает, какие поля копируются. Копия начинает с теми же данными, что у оригинала, а дальше два объекта живут независимо. Как читать пример. Прототип - это фигура с одним значением, например цветом или числом сторон. В большинстве языков объект-клиент держит один прототип, а новые фигуры получает только одним способом - просит у него копию. Вывод показывает, что у копий то же значение, что у прототипа. Некоторые примеры показывают ещё, что копия - отдельный объект или что изменение копии не трогает прототип. В языках, где значения никогда не меняются, ничего не копируется: новый вариант - это тот же образец с одним изменённым полем. Когда применять. Прототип нужен, когда объект дорого подготовить, а похожих объектов требуется много. Он помогает и тогда, когда класс создаваемого объекта становится известен только во время работы программы. Для простых объектов с немногими полями он ни к чему: конструктор проще. Частая ошибка. Написать метод копирования только в базовом классе, так что он всегда создаёт базовый объект. Копия конкретного прототипа тогда теряет свой класс. Каждый конкретный прототип должен создавать объект своего класса. |