Створення читалки електронних книг: Мок-співбесіда з об’єктно-орієнтованого проектування на C#

1. Вступ

Ласкаво просимо до останнього випуску нашої серії блогів про об'єктно-орієнтоване програмування (OOP) на C#! Протягом цієї серії ми досліджували основи OOP, просунуті концепції та шаблони проектування за допомогою практичних прикладів. Тепер настав час об'єднати все в реальному сценарії.

У цьому пості ми розглянемо поширене запитання на співбесіді з об'єктно-орієнтованого проектування: розробку додатку для читання електронних книг (eBook). Це чудовий випадок для демонстрації того, як принципи OOP можуть бути застосовані для ефективного вирішення реальних проблем. Від визначення вимог до системи до реалізації рішення на C#, ми покроково проведемо вас через весь процес.

Якщо ви готуєтеся до технічної співбесіди або хочете поглибити розуміння OOP, цей пост надасть корисні поради та практичні техніки. Давайте розглянемо опис проблеми та почнемо проектування!

2. Опис проблеми

Вам запропонували розробити додаток для читання електронних книг (eBook). Цей додаток має дозволяти користувачам управляти їх цифровою бібліотекою, читати книги та відслідковувати свій прогрес у читанні. Ось вимоги:

Функціональні вимоги

Управління бібліотекою:

  • Користувачі можуть додавати книги до своєї персональної бібліотеки.
  • Користувачі можуть видаляти книги зі своєї бібліотеки.

Функціональність читання:

  • Користувачі можуть вибирати книгу зі своєї бібліотеки як активну.
  • Додаток повинен відображати одну сторінку тексту за раз.
  • Користувачі можуть переміщатися між сторінками (наступна/попередня).
  • Прогрес читання має зберігатися (наприклад, запам'ятовувати останню прочитану сторінку).

Припущення

  • Початкова реалізація буде орієнтована на сценарій одного користувача (без багатокористувацького режиму).
  • Контент електронних книг буде простим текстом без складного форматування, як розмір шрифту тощо.

3. Проектування системи

Архітектура високого рівня

Система буде складатися з трьох основних компонентів:

  1. Бібліотека: відповідає за управління колекцією книг у бібліотеці користувача.
  2. ЧитачКниг: обробляє функціональність читання, включаючи навігацію та закладки.
  3. Книга: представляє окрему електронну книгу та її зміст.

Основні класи та їх обов'язки

Library:

  • Керує колекцією книг користувача.
  • Методи:
    • AddBook(Book book): додає книгу до бібліотеки.
    • RemoveBook(string title): видаляє книгу за назвою.
    • GetBook(int bookId): отримує книгу за її bookId.

BookReader:

  • Керує активною сесією читання.
  • Методи:
    • OpenBook(Book book): встановлює активну книгу.
    • NextPage(): переходить до наступної сторінки.
    • PreviousPage(): переходить до попередньої сторінки.
    • GetCurrentPage(): отримує зміст поточної сторінки.
    • BookmarkPage(): зберігає поточну сторінку як закладку.

Book:

  • Представляє електронну книгу.
  • Властивості:
    • Title: назва книги.
    • BookId: ідентифікатор книги.
    • Author: автор книги.
    • Content: простий текст змісту книги, розбитий на сторінки.
    • Bookmark: номер останньої прочитаної сторінки.
  • Методи:
    • GetPage(int pageNumber): отримує зміст конкретної сторінки.

Потік даних

  1. Користувач взаємодіє з Бібліотекою для додавання чи видалення книг.
  2. Коли книга вибрана, вона передається до ЧитачаКниг для читання.
  3. ЧитачКниг отримує зміст з класу Книга та керує навігацією і закладками.

Приклад потоку:

  1. Користувач додає нову книгу до своєї бібліотеки за допомогою Library.AddBook().
  2. Користувач вибирає книгу для читання, викликаючи BookReader.OpenBook().
  3. ЧитачКниг відображає першу сторінку за допомогою Book.GetPage(1).
  4. Користувач переходить на наступну сторінку, викликаючи BookReader.NextPage().
  5. Користувач зберігає поточну сторінку як закладку, викликаючи BookReader.BookmarkPage().
    # Реалізація на C#

Нижче наведена покрокова реалізація основних функцій додатку для читання електронних книг (eBook):

Крок 1: Опис класу Book

public class Book  
{  
 public int BookId { get; set; }  
 public string Title { get; set; }  
 public string Author { get; set; }  
 public List Content { get; set; } // Контент, розбитий на сторінки  
 public int Bookmark { get; set; } // Остання прочитана сторінка  

 public Book(int bookId, string title, string author, List content)  
 {  
 BookId = bookId;  
 Title = title;  
 Author = author;  
 Content = content;  
 Bookmark = 0; // Починаємо з першої сторінки  
 }  
 public string GetPage(int pageNumber)  
 {  
 if (pageNumber < 0 || pageNumber >= Content.Count)  
 {  
 return "Невірний номер сторінки.";  
 }  
 return Content[pageNumber];  
 }  
}

Крок 2: Опис класу Library

public class Library  
{  
 private List Library = new List();  

 public void AddBook(Book book)  
 {  
 Library.Add(book);  
 }  
 public void RemoveBook(int bookId)  
 {  
 Library.RemoveAll(b => b.BookId == bookId);  
 }  
 public Book GetBook(int bookId)  
 {  
 return Library.FirstOrDefault(b => b.BookId == bookId);  
 }  
}

Крок 3: Опис класу BookReader

public class BookReader  
{  
 private Book ActiveBook;  
 private int CurrentPage;  

 public void OpenBook(Book book)  
 {  
 ActiveBook = book;  
 CurrentPage = book.Bookmark;  
 }  
 public string GetCurrentPage()  
 {  
 return ActiveBook?.GetPage(CurrentPage) ?? "Немає відкритої книги.";  
 }  
 public void NextPage()  
 {  
 if (ActiveBook != null && CurrentPage < ActiveBook.Content.Count - 1)  
 {  
 CurrentPage++;  
 }  
 }  
 public void PreviousPage()  
 {  
 if (ActiveBook != null && CurrentPage > 0)  
 {  
 CurrentPage--;  
 }  
 }  
 public void BookmarkPage()  
 {  
 if (ActiveBook != null)  
 {  
 ActiveBook.Bookmark = CurrentPage;  
 }  
 }  
}

Пояснення коду

Клас Book:

  • Представляє електронну книгу з властивостями для ідентифікатора, назви, автора, контенту та закладки.
  • Обробляє отримання конкретної сторінки за допомогою методу GetPage().

Клас Library:

  • Керує колекцією книг з методами для додавання, видалення та отримання книг за їх bookId.

Клас BookReader:

  • Керує активною сесією читання, включаючи навігацію та закладки.
  • Взаємодіє з класом Book для отримання та відображення контенту.

5. Налаштування бази даних

Для підтримки функціональності додатку система потребує двох окремих рішень для зберігання:

1. Зберігання метаданих (Реляційна база даних)

Зберігає інформацію про бібліотеки, книги та прогрес користувача.

Проектування таблиць

Таблиця Library:

  • LibraryId (Первинний ключ): Унікальний ідентифікатор для кожної бібліотеки.
  • BookIds (формат JSON): JSON-масив, що містить BookId книг у бібліотеці.
  • UserId: Необов'язкове поле для підтримки багатокористувацького режиму в майбутньому.
| LibraryId | BookIds | UserId |  
|-----------|----------------------|--------|  
| 1 | [101, 102, 103] | null |  
| 2 | [104, 105] | null |

Таблиця Book:

  • BookId (Первинний ключ): Унікальний ідентифікатор кожної книги.
  • Title: Назва книги.
  • Author: Автор книги.
  • Bookmark: Остання прочитана сторінка (прогрес).
| BookId | Title | Author | Bookmark |  
|--------|----------------|----------------|----------|  
| 101 | "C# Basics" | "John Smith" | 5 |  
| 102 | "OOP Design" | "Jane Doe" | 12 |  
| 103 | "System Design"| "Alex White" | 0 |

2. Зберігання контенту (Файлова система або об'єктне зберігання)

Зберігає фактичний контент книг. Кожен контент книги поділений на сторінки та збережений у файловій системі або в рішенні об'єктного зберігання (наприклад, AWS S3, Azure Blob Storage).

Конвенція іменування файлів

  • Файли іменуються за допомогою BookId для легкості отримання.
  • Приклад: 101.txt, 102.txt

Структура каталогів:

/content_storage/  
 101.txt  
 102.txt  
 103.txt

Як це працює

1.
Коли користувач додає книгу до своєї бібліотеки, BookId додається до масиву BookIds у форматі JSON в таблиці Library.
2. Коли користувач відкриває книгу, система отримує її метадані з таблиці Book і завантажує файл контенту з файлової системи.
3. Прогрес читання (наприклад, закладки) оновлюється в таблиці Book.

Для взаємодії з базою даних необхідно визначити класи об'єктно-орієнтованого доступу до даних (DAO), які оброблятимуть операції збереження та запиту даних. Шар DAO включатиме методи для перетворення реляційних даних в об'єкти і навпаки.

6. Висновок

Основні висновки

  • Розуміння та реалізація принципів об'єктно-орієнтованого програмування є критичними для проектування масштабованих і підтримуваних систем.
  • Шаблони проектування, такі як Singleton, Factory та Observer, можуть значно покращити проектування вашого додатку.
  • Проектування бази даних та класи DAO відіграють важливу роль у ефективному управлінні постійними даними.

Поради для вирішення подібних питань на співбесідах

  • Розбийте задачу на менші, керовані частини.
  • Зосередьтеся на вимогах і переконайтеся, що ваше рішення їм відповідає.
  • Використовуйте UML-діаграми або псевдокод, щоб чітко передати свій процес мислення.
  • Виділіть використання шаблонів проектування та обґрунтуйте свої рішення щодо дизайну.

З таким підходом ви будете добре підготовлені до вирішення питань щодо об'єктно-орієнтованого проектування на технічних співбесідах.

Перекладено з: Building an eBook Reader: Mock Interview in C# Object-Oriented Design

Leave a Reply

Your email address will not be published. Required fields are marked *