Статические инициализаторы (`static`) выполняются один раз при загрузке класса и инициализируют статические переменные.
Нестатические инициализаторы выполняются при создании каждого экземпляра класса и используются для инициализации нестатических переменных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Использование наследования может привести к жесткой связности и сложностям в поддержке кода. Альтернативы наследованию: композиция, протоколы (интерфейсы), расширения (extensions) и делегирование. Эти подходы обеспечивают большую гибкость и модульность.
Композиция включает объекты других классов как поля и делегирует им работу, что позволяет гибко изменять поведение во время выполнения.
protocol Engine {
func start()
}
class Car {
private let engine: Engine
init(engine: Engine) {
self.engine = engine
}
func start() {
engine.start()
}
}
class ElectricEngine: Engine {
func start() {
print("Electric engine starting...")
}
}
class GasolineEngine: Engine {
func start() {
print("Gasoline engine starting...")
}
}
let electricCar = Car(engine: ElectricEngine())
let gasolineCar = Car(engine: GasolineEngine())
electricCar.start()
gasolineCar.start()Протоколы определяют набор методов и свойств, которые класс или структура должны реализовать, обеспечивая гибкость и переиспользуемость компонентов.
protocol Drawable {
func draw()
}
class Circle: Drawable {
func draw() {
print("Drawing a circle")
}
}
class Square: Drawable {
func draw() {
print("Drawing a square")
}
}
func render(drawable: Drawable) {
drawable.draw()
}
let shapes: [Drawable] = [Circle(), Square()]
shapes.forEach { render(drawable: $0) }Расширения добавляют новые методы и свойства к существующим классам, структурам или перечислениям без изменения исходного кода.
extension String {
func reverse() -> String {
return String(self.reversed())
}
}
let original = "hello"
let reversed = original.reverse()
print(reversed) // "olleh"Делегирование передает ответственность за выполнение задач другому объекту, создавая гибкие и переиспользуемые компоненты.
protocol PrinterDelegate: AnyObject {
func printerDidFinishPrinting(_ printer: Printer)
}
class Printer {
weak var delegate: PrinterDelegate?
func printDocument() {
print("Printing document...")
delegate?.printerDidFinishPrinting(self)
}
}
class PrintManager: PrinterDelegate {
func printerDidFinishPrinting(_ printer: Printer) {
print("Document printing completed.")
}
}
let printer = Printer()
let manager = PrintManager()
printer.delegate = manager
printer.printDocument()Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
Reference type (ссылочный тип) хранит ссылку на область памяти, где находятся данные, и при копировании копируется только ссылка, а не сами данные. Например, объекты классов разделяют одну и ту же память.
Разница проявляется при изменении данных: value type остаётся неизменным в копиях, а reference type отражает изменения во всех ссылках.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
В объектно-ориентированном программировании классы могут выполнять различные роли в зависимости от их назначения и использования. Классы, условно названные
User и Data, могут иметь существенные различия в своей реализации и предназначении. Класс
User обычно представляет сущность пользователя в системе. Он может включать свойства и методы, специфичные для пользователя, такие как идентификатор, имя, адрес электронной почты и методы для управления этими данными.class User {
var id: Int
var name: String
var email: String
init(id: Int, name: String, email: String) {
self.id = id
self.name = name
self.email = email
}
func updateEmail(newEmail: String) {
self.email = newEmail
}
}Класс
Data чаще всего используется для представления необработанных данных или байтов. В Swift, например, Data — это структура из Foundation, которая предоставляет интерфейс для работы с бинарными данными.import Foundation
let string = "Hello, World!"
if let data = string.data(using: .utf8) {
// Преобразование строки в Data
print(data)
}
let jsonString = "{\"name\": \"John\", \"age\": 30}"
if let jsonData = jsonString.data(using: .utf8) {
// Преобразование JSON-строки в Data
do {
if let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
print(jsonObject)
}
} catch {
print("Ошибка парсинга JSON: \(error)")
}
}
User: Представляет конкретную сущность пользователя в системе. Используется для управления и хранения данных о пользователе.
Data: Представляет необработанные данные или байты. Используется для операций с бинарными данными, таких как чтение и запись файлов, сетевые операции и сериализация.
User: Обычно содержит несколько свойств, специфичных для пользователя, и методы для управления этими данными.
Data: Является универсальным контейнером для байтов, предоставляя методы для работы с этими данными.
User: Включен в бизнес-логику, тесно связан с функциональностью приложения, связанной с пользователями.
Data: Используется для низкоуровневых операций с данными, часто не связан напрямую с бизнес-логикой.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1😁1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚Базу Знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Приложения на Swift могут быть массивными из-за нескольких факторов:
Включает много функций и структур данных, что увеличивает размер бинарного файла.
Современные приложения часто используют множество внешних библиотек и фреймворков, добавляющих объем.
Компиляция для разных архитектур (например, arm64, x86_64) увеличивает размер исполняемого файла.
Большое количество изображений, видео и аудиофайлов увеличивают размер приложения.
Включение символов отладки для разработки и анализа сбоев добавляет объем.
Статические библиотеки увеличивают размер исполняемого файла по сравнению с динамическими.
Поддержка старых версий iOS требует включения дополнительных библиотек и кода.
Использование инструментов для удаления лишних архитектур из финальной сборки.
Сжатие изображений и видео, использование эффективных форматов.
Исключение символов отладки в релизной сборке.
Использование динамических библиотек для уменьшения размера основного исполняемого файла.
Удаление неиспользуемого кода и зависимостей.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
PO вызывает методы description или debugDescription, которые могут изменять состояние объекта.Тяжелые вычисления в методах
description или debugDescription могут замедлить отладку.Доступ к объекту в многопоточной среде может привести к состоянию гонки.
Ошибки в методах
description или debugDescription могут привести к сбоям при использовании PO.Методы, использующие блокировки, могут привести к зависанию отладчика.
Побочные эффекты
class DangerousObject {
var counter = 0
var description: String {
counter += 1 // Изменение состояния
return "Counter: \(counter)"
}
}Производительность
class HeavyObject {
var description: String {
let result = (0..<1_000_000).map { $0 * $0 }.reduce(0, +)
return "Result: \(result)"
}
}Проблемы с потоками
class ThreadUnsafeObject {
var data = [Int]()
var description: String {
return "Data count: \(data.count)"
}
}Краш приложения
class CrashObject {
var description: String {
fatalError("Should not be called")
}
}Зависания
class LockObject {
let lock = NSLock()
var description: String {
lock.lock()
defer { lock.unlock() }
return "Locked"
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это текстовый протокол для общения в реальном времени. Он позволяет пользователям обмениваться сообщениями в каналах (чат-румах) или через личные сообщения.
Объединяют пользователей для обсуждения общих тем.
Прямой обмен сообщениями между пользователями.
Поддерживают несколько каналов и управляют соединениями пользователей.
Программы, используемые для подключения к IRC-серверам и участия в чатах.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Механизм синхронизации
Synchronized под капотом обеспечивает контроль доступа к критическим секциям кода в многопоточных приложениях, предотвращая состояние гонки и гарантируя, что только один поток в данный момент времени имеет доступ к определенному ресурсу.Различные механизмы синхронизации реализуют
Synchronized по-разному, но общая идея заключается в использовании блокировок (локов), чтобы обеспечить эксклюзивный доступ к ресурсу.Это простая блокировка, предоставляемая Foundation framework в Swift:
class ThreadSafeClass {
private var internalState = 0
private let lock = NSLock()
func increment() {
lock.lock()
internalState += 1
lock.unlock()
}
func getState() -> Int {
lock.lock()
let state = internalState
lock.unlock()
return state
}
}DispatchQueue позволяет организовать выполнение кода в синхронном или асинхронном режиме. class ThreadSafeClass {
private var internalState = 0
private let queue = DispatchQueue(label: "com.example.threadSafeQueue")
func increment() {
queue.sync {
internalState += 1
}
}
func getState() -> Int {
return queue.sync {
internalState
}
}
}Эти функции используются для синхронизации в Objective-C и могут быть использованы в Swift.
class ThreadSafeClass: NSObject {
private var internalState = 0
func increment() {
objc_sync_enter(self)
internalState += 1
objc_sync_exit(self)
}
func getState() -> Int {
objc_sync_enter(self)
let state = internalState
objc_sync_exit(self)
return state
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
Выделения в программировании касаются процессов управления памятью, когда память выделяется (аллоцируется) и освобождается (деаллоцируется) для использования программой. В современных языках программирования эти процессы могут быть управляемыми вручную или автоматически.
Статическая аллокация: Память выделяется во время компиляции и существует на протяжении всего времени выполнения программы. Используется для глобальных и статических переменных.
int globalVar = 10; // Статическая память
Стековая аллокация: Память выделяется при вызове функции и освобождается при выходе из функции. Используется для локальных переменных.
void function() {
int localVar = 20; // Стековая память
}Куча (динамическая аллокация): Память выделяется по запросу во время выполнения программы и освобождается вручную (в языках с ручным управлением памятью) или автоматически (в языках с автоматическим управлением памятью, например, через сборщик мусора).
int *ptr = (int*)malloc(sizeof(int) * 10); // Выделение памяти в куче
free(ptr); // Освобождение памяти
Вручную: Программист отвечает за освобождение памяти, выделенной в куче.
free(ptr);
Автоматически: Сборщик мусора (Garbage Collector) автоматически освобождает память, которая больше не используется.
// В Java нет необходимости освобождать память вручную.
C/C++ (ручное управление памятью):
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = (int*)malloc(sizeof(int) * 5); // Выделение памяти
if (arr == NULL) {
// Ошибка выделения памяти
return 1;
}
// Использование массива
for (int i = 0; i < 5; i++) {
arr[i] = i;
}
// Освобождение памяти
free(arr);
return 0;
}
Python (автоматическое управление памятью):
def create_list():
my_list = [i for i in range(5)] # Выделение памяти автоматически
return my_list # Память освобождается автоматически, когда объект больше не используется
my_list = create_list()
print(my_list)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1🤔1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
Это система документирования, которая используется для описания кода на языке JavaScript. Она позволяет разработчикам комментировать свой код специальными метками и описаниями, что облегчает его понимание и поддержку. Одной из самых популярных систем документирования в JavaScript является JSDoc.
JSDoc позволяет автоматически создавать HTML-документацию из аннотированных комментариев в коде.
JSDoc позволяет описывать типы данных параметров и возвращаемых значений функций.
JSDoc используется для документирования всех аспектов кода, включая функции, методы, классы и модули.
/**
* Adds two numbers together.
* @param {number} a - The first number.
* @param {number} b - The second number.
* @returns {number} The sum of the two numbers.
*/
function add(a, b) {
return a + b;
}
/**
* Represents a person.
* @class
*/
class Person {
/**
* Creates a person.
* @param {string} name - The name of the person.
* @param {number} age - The age of the person.
*/
constructor(name, age) {
this.name = name;
this.age = age;
}
/**
* Greets someone.
* @param {string} [greetName='Stranger'] - The name of the person to greet.
* @returns {string} The greeting message.
*/
greet(greetName = 'Stranger') {
return `Hello, ${greetName}! My name is ${this.name}.`;
}
}
@param — Описание параметров функции.@returns — Описание возвращаемого значения функции.@class — Описание класса.@constructor — Описание конструктора класса.@typedef — Описание типа данных.Комментарии JSDoc помогают другим разработчикам быстрее понять структуру и назначение кода.
Генерация документации упрощает поддержание актуальности документации и кода.
Некоторые инструменты могут использовать JSDoc для улучшения статического анализа кода, предоставляя более точные подсказки и проверки типов.
Для генерации документации с использованием JSDoc требуется установить и использовать инструмент командной строки JSDoc.
npm install -g jsdoc
jsdoc yourJavaScriptFile.js
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔4❤1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Да, в JavaScript, а также в других языках программирования, концепция Event Emitter (или Event Dispatcher) используется для работы с событиями и позволяет компонентам взаимодействовать друг с другом, подписываясь на события и реагируя на них. В JavaScript это часто реализуется с использованием колбэков.
В JavaScript Event Emitter часто используется с помощью библиотеки
events, которая встроена в Node.js. Вот как это работаетconst EventEmitter = require('events');
const eventEmitter = new EventEmitter();
// Подписка на событие 'event'
eventEmitter.on('event', (message) => {
console.log(`Received event with message: ${message}`);
});// Инициация события 'event'
eventEmitter.emit('event', 'Hello, World!');
В браузере события также часто обрабатываются с использованием колбэков через API, такие как
addEventListener.const button = document.getElementById('myButton');
// Подписка на событие 'click'
button.addEventListener('click', () => {
console.log('Button clicked!');
});// Инициация события 'click'
button.click();
Можно создать собственный класс EventEmitter, который будет использовать колбэки для обработки событий.
class EventEmitter {
constructor() {
this.events = {};
}
on(event, listener) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(listener);
}
emit(event, ...args) {
if (this.events[event]) {
this.events[event].forEach(listener => listener(...args));
}
}
off(event, listener) {
if (this.events[event]) {
this.events[event] = this.events[event].filter(l => l !== listener);
}
}
}
// Использование:
const emitter = new EventEmitter();
// Подписка на событие
emitter.on('message', (msg) => {
console.log(`Message: ${msg}`);
});
// Инициация события
emitter.emit('message', 'Hello, Event Emitter!');Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯4❤2😁1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Это подход к разработке, который фокусируется на моделировании доменной области. Вот основные признаки, по которым можно отличить DDD в приложении:
Ubiquitous Language: Общий язык, используемый всей командой.
Доменные объекты: Сущности, значимые объекты, агрегаты, доменные события.
Доменный слой: Содержит модели, агрегаты, репозитории, доменные сервисы.
Слой приложений: Управляет потоками работы и координирует доменные объекты.
Инфраструктурный слой: Реализация репозиториев, доступ к базам данных.
Презентационный слой: Взаимодействие с пользователем.
Репозитории: Обеспечивают доступ к агрегатам.
Фабрики: Управляют созданием сложных объектов.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM