Читаем Язык программирования C#9 и платформа .NET5 полностью

В текущей реализации MediaPlayer предполагается, что пользователь объекта пожелает получать список объектов с помощью метода GetAllTracks. Хорошо, а что если пользователю объекта такой список не нужен? В этой реализации память под переменную-член AllTracks по-прежнему будет выделяться, приводя тем самым к созданию 10 000 объектов Song в памяти:


using System;

using LazyObjectInstantiation;

Console.WriteLine("***** Fun with Lazy Instantiation *****\n");

// В этом вызывающем коде получение всех композиций не производится,

// но косвенно все равно создаются 10 000 объектов!

MediaPlayer myPlayer = new MediaPlayer;

myPlayer.Play;

Console.ReadLine;


Безусловно, лучше не создавать 10 000 объектов, с которыми никто не будет работать, потому что в результате нагрузка на сборщик мусора .NET Core намного увеличится. В то время как можно вручную добавить код, который обеспечит создание объекта _allSongs только в случае, если он применяется (скажем, используя шаблон фабричного метода), есть более простой путь.

Библиотеки базовых классов предоставляют удобный обобщенный класс по имени Lazy<>, который определен в пространстве имен System внутри сборки mscorlib.dll. Он позволяет определять данные, которые не будут создаваться до тех пор, пока действительно не начнут применяться в коде. Поскольку класс является обобщенным, при первом его использовании вы должны явно указать тип создаваемого элемента, которым может быть любой тип из библиотек базовых классов .NET Core или специальный тип, построенный вами самостоятельно. Чтобы включить отложенную инициализацию переменной-члена AllTracks, просто приведите код MediaPlayer к следующему виду:


// Объект MediaPlayer имеет объект Lazy.

class MediaPlayer

{

  ...

  private Lazy _allSongs = new Lazy;

  public AllTracks GetAllTracks

  {

    // Возвратить все композиции.

    return _allSongs.Value;

  }

}


Помимо того факта, что переменная-член AllTracks теперь имеет тип Lazy<>, важно обратить внимание на изменение также и реализации показанного выше метода GetAllTracks. В частности, для получения актуальных сохраненных данных (в этом случае объекта AllTracks, поддерживающего 10 000 объектов Song) должно применяться доступное только для чтения свойство Value класса Lazy<>.

Взгляните, как благодаря такому простому изменению приведенный далее модифицированный код будет косвенно размещать объекты Song в памяти, только если метод GetAllTracks действительно вызывается:


Console.WriteLine("***** Fun with Lazy Instantiation *****\n");

//  Память под объект AllTracks здесь не выделяется!

MediaPlayer myPlayer = new MediaPlayer;

myPlayer.Play;

// Размещение объекта AllTracks происходит

// только в случае вызова метода GetAllTracks.

MediaPlayer yourPlayer = new MediaPlayer;

AllTracks yourMusic = yourPlayer.GetAllTracks;

Console.ReadLine;


На заметку! Ленивое создание объектов полезно не только для уменьшения количества выделений памяти под ненужные объекты. Этот прием можно также использовать в ситуации, когда для создания члена применяется затратный в плане ресурсов код, такой как вызов удаленного метода, взаимодействие с реляционной базой данных и т.п.

Настройка процесса создания данных Lazy<>

При объявлении переменной Lazy действительный внутренний тип данных создается с использованием стандартного конструктора:


// При использовании переменной Lazy вызывается

// стандартный конструктор класса AllTracks.

private Lazy _allSongs = new Lazy;


В некоторых случаях приведенный код может оказаться приемлемым, но что если класс AllTracks имеет дополнительные конструкторы и нужно обеспечить вызов подходящего конструктора? Более того, что если при создании переменной Lazy должна выполняться какая-то специальная работа (кроме простого создания объекта AllTracks)? К счастью, класс Lazy позволяет указывать в качестве необязательного параметра обобщенный делегат, который задает метод для вызова во время создания находящегося внутри типа.

Перейти на страницу:

Похожие книги

Программирование. Принципы и практика использования C++ Исправленное издание
Программирование. Принципы и практика использования C++ Исправленное издание

Специальное издание самой читаемой и содержащей наиболее достоверные сведения книги по C++. Книга написана Бьярне Страуструпом — автором языка программирования C++ — и является каноническим изложением возможностей этого языка. Помимо подробного описания собственно языка, на страницах книги вы найдете доказавшие свою эффективность подходы к решению разнообразных задач проектирования и программирования. Многочисленные примеры демонстрируют как хороший стиль программирования на С-совместимом ядре C++, так и современный -ориентированный подход к созданию программных продуктов. Третье издание бестселлера было существенно переработано автором. Результатом этой переработки стала большая доступность книги для новичков. В то же время, текст обогатился сведениями и методиками программирования, которые могут оказаться полезными даже для многоопытных специалистов по C++. Не обойдены вниманием и нововведения языка: стандартная библиотека шаблонов (STL), пространства имен (namespaces), механизм идентификации типов во время выполнения (RTTI), явные приведения типов (cast-операторы) и другие. Настоящее специальное издание отличается от третьего добавлением двух новых приложений (посвященных локализации и безопасной обработке исключений средствами стандартной библиотеки), довольно многочисленными уточнениями в остальном тексте, а также исправлением множества опечаток. Книга адресована программистам, использующим в своей повседневной работе C++. Она также будет полезна преподавателям, студентам и всем, кто хочет ознакомиться с описанием языка «из первых рук».

Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов

Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT
97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

Успешная карьера архитектора программного обеспечения требует хорошего владения как технической, так и деловой сторонами вопросов, связанных с проектированием архитектуры. В этой необычной книге ведущие архитекторы ПО со всего света обсуждают важные принципы разработки, выходящие далеко за пределы чисто технических вопросов.?Архитектор ПО выполняет роль посредника между командой разработчиков и бизнес-руководством компании, поэтому чтобы добиться успеха в этой профессии, необходимо не только овладеть различными технологиями, но и обеспечить работу над проектом в соответствии с бизнес-целями. В книге более 50 архитекторов рассказывают о том, что считают самым важным в своей работе, дают советы, как организовать общение с другими участниками проекта, как снизить сложность архитектуры, как оказывать поддержку разработчикам. Они щедро делятся множеством полезных идей и приемов, которые вынесли из своего многолетнего опыта. Авторы надеются, что книга станет источником вдохновения и руководством к действию для многих профессиональных программистов.

Нил Форд , Билл де Ора , Майкл Хайгард

Программирование, программы, базы данных / Базы данных / Программирование / Книги по IT