Выделения в программировании касаются процессов управления памятью, когда память выделяется (аллоцируется) и освобождается (деаллоцируется) для использования программой. В современных языках программирования эти процессы могут быть управляемыми вручную или автоматически.
Статическая аллокация: Память выделяется во время компиляции и существует на протяжении всего времени выполнения программы. Используется для глобальных и статических переменных.
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
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Да, Promises часто используются в JavaScript для управления асинхронными операциями, но они сами по себе не пишутся на колбеках. Вместо этого Promises используются как альтернатива колбекам, чтобы упростить управление асинхронным кодом и сделать его более читаемым и предсказуемым. Вот как можно использовать Promises вместо колбеков для управления асинхронным кодом:
function fetchData(callback) {
setTimeout(() => {
callback("Data received");
}, 1000);
}
fetchData((data) => {
console.log(data); // "Data received"
});function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Data received");
}, 1000);
});
}
fetchData().then((data) => {
console.log(data); // "Data received"
});Promises помогают избежать вложенности колбеков (callback hell), делая код более линейным и читаемым.
Promises обеспечивают единый механизм обработки ошибок с помощью
.catch(), что упрощает отладку.Promises поддерживают цепочки вызовов (
.then()), что упрощает выполнение последовательных асинхронных операций.Современный синтаксис JavaScript включает
async/await, который еще больше упрощает работу с асинхронным кодом на основе Promises, делая его похожим на синхронный код.function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Data received");
}, 1000);
});
}
async function fetchDataAsync() {
try {
const data = await fetchData();
console.log(data); // "Data received"
} catch (error) {
console.error(error);
}
}
fetchDataAsync();Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1😁1
В Domain-Driven Design (DDD) управление зависимостями важно для создания четко разделенных и легко управляемых компонентов. Это достигается следующими методами:
Инъекция зависимостей позволяет передавать зависимости через конструкторы или сеттеры, снижая связанность и упрощая тестирование.
interface UserRepository {
findById(id: string): Promise<User | null>;
}
class UserService {
private userRepository: UserRepository;
constructor(userRepository: UserRepository) {
this.userRepository = userRepository;
}
public async getUserById(id: string): Promise<User | null> {
return await this.userRepository.findById(id);
}
}Сервисы домена содержат бизнес-логику, не принадлежащую конкретным сущностям или значимым объектам, и могут взаимодействовать с несколькими объектами или внешними сервисами.
class PaymentService {
private paymentGateway: PaymentGateway;
constructor(paymentGateway: PaymentGateway) {
this.paymentGateway = paymentGateway;
}
public async processPayment(order: Order): Promise<boolean> {
return await this.paymentGateway.charge(order.totalAmount);
}
}Анти-коррупционные слои защищают доменную модель от внешних влияний и преобразуют данные в понятные форматы.
class ExternalUserService {
public getUserData(id: string): ExternalUser {
// Получение данных от внешнего сервиса
}
}
class UserService {
private externalUserService: ExternalUserService;
constructor(externalUserService: ExternalUserService) {
this.externalUserService = externalUserService;
}
public getUser(id: string): User {
const externalUser = this.externalUserService.getUserData(id);
return new User(externalUser.id, externalUser.name, externalUser.email);
}
}Контейнеры управляют созданием и жизненным циклом зависимостей, упрощая конфигурацию и разрешение зависимостей.
import "reflect-metadata";
import { Container, injectable, inject } from "inversify";
@injectable()
class UserRepositoryImpl implements UserRepository {
public async findById(id: string): Promise<User | null> {
// Реализация метода
}
}
@injectable()
class UserService {
private userRepository: UserRepository;
constructor(@inject("UserRepository") userRepository: UserRepository) {
this.userRepository = userRepository;
}
public async getUserById(id: string): Promise<User | null> {
return await this.userRepository.findById(id);
}
}
// Конфигурация контейнера
const container = new Container();
container.bind<UserRepository>("UserRepository").to(UserRepositoryImpl);
container.bind<UserService>(UserService).toSelf();
// Разрешение зависимостей
const userService = container.get<UserService>(UserService);
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Связывание интерфейсов с конкретными реализациями осуществляется через инъекцию зависимостей (Dependency Injection), фабрики (Factories) и контейнеры зависимостей (Dependency Injection Containers). Эти методы абстрагируют зависимости и упрощают замену реализаций.
Инъекция зависимостей передает зависимости через конструкторы, сеттеры или методы, обеспечивая гибкость и упрощая тестирование.
interface UserRepository {
findById(id: string): Promise<User | null>;
}
class UserRepositoryImpl implements UserRepository {
public async findById(id: string): Promise<User | null> {
return { id, name: "John Doe" };
}
}
class UserService {
private userRepository: UserRepository;
constructor(userRepository: UserRepository) {
this.userRepository = userRepository;
}
public async getUserById(id: string): Promise<User | null> {
return await this.userRepository.findById(id);
}
}
const userRepository = new UserRepositoryImpl();
const userService = new UserService(userRepository);Фабрики создают объекты, инкапсулируя логику создания и облегчая управление.
interface UserRepository {
findById(id: string): Promise<User | null>;
}
class UserRepositoryImpl implements UserRepository {
public async findById(id: string): Promise<User | null> {
return { id, name: "John Doe" };
}
}
class UserRepositoryFactory {
static create(): UserRepository {
return new UserRepositoryImpl();
}
}
const userRepository = UserRepositoryFactory.create();
const userService = new UserService(userRepository);Контейнеры управляют созданием и разрешением зависимостей централизованно.
import "reflect-metadata";
import { Container, injectable, inject } from "inversify";
interface UserRepository {
findById(id: string): Promise<User | null>;
}
@injectable()
class UserRepositoryImpl implements UserRepository {
public async findById(id: string): Promise<User | null> {
return { id, name: "John Doe" };
}
}
@injectable()
class UserService {
private userRepository: UserRepository;
constructor(@inject("UserRepository") userRepository: UserRepository) {
this.userRepository = userRepository;
}
public async getUserById(id: string): Promise<User | null> {
return await this.userRepository.findById(id);
}
}
const container = new Container();
container.bind<UserRepository>("UserRepository").to(UserRepositoryImpl);
container.bind<UserService>(UserService).toSelf();
const userService = container.get<UserService>(UserService);
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3😁1
Singletone нарушает несколько принципов хорошего проектирования кода, особенно из набора принципов SOLID.
Класс должен иметь только одну причину для изменения. Singletone выполняет две задачи: управляет своим состоянием и контролирует создание своего единственного экземпляра. Это смешивание обязанностей делает класс сложнее и приводит к ситуации, когда изменение в одной из обязанностей может повлиять на другую.
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
def some_business_logic(self):
pass
# Здесь Singleton отвечает за управление состоянием и контролем создания экземпляра
Классы должны быть открыты для расширения, но закрыты для модификации. Singletone трудно расширять без модификации его кода. Для изменения логики создания экземпляра или поведения необходимо изменять сам класс, что нарушает OCP.
Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба типа модулей должны зависеть от абстракций. Singletone нарушает DIP, так как привязывает код к конкретной реализации через глобальный доступ к своему экземпляру. Это делает тестирование и замену реализации сложными, поскольку зависимость жестко закодирована.
class DatabaseConnection:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(DatabaseConnection, cls).__new__(cls, *args, **kwargs)
return cls._instance
# Любой код, использующий DatabaseConnection, теперь жестко привязан к этой реализации
Может создавать скрытые зависимости: Singletone часто используют глобальные состояния, которые могут усложнить тестирование. Сложность при мокировании: Из-за глобального доступа к синглтону сложно подменить его поведение в тестах.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Полиморфизм широко используется в iOS разработке для создания гибкого и расширяемого кода.
Протоколы в Swift позволяют определять методы и свойства, которые классы, структуры или перечисления должны реализовать. Это позволяет создавать полиморфные интерфейсы, которые могут быть реализованы различными типами.
protocol Drawable {
func draw()
}
class Circle: Drawable {
func draw() {
print("Drawing a circle")
}
}
class Square: Drawable {
func draw() {
print("Drawing a square")
}
}
func renderShape(_ shape: Drawable) {
shape.draw()
}
let shapes: [Drawable] = [Circle(), Square()]
for shape in shapes {
renderShape(shape) // Полиморфный вызов метода draw()
}Классы могут наследовать методы и свойства от родительских классов, что позволяет использовать полиморфизм через переопределение методов.
class Animal {
func makeSound() {
print("Some generic animal sound")
}
}
class Dog: Animal {
override func makeSound() {
print("Bark")
}
}
class Cat: Animal {
override func makeSound() {
print("Meow")
}
}
let animals: [Animal] = [Dog(), Cat()]
for animal in animals {
animal.makeSound() // Полиморфный вызов метода makeSound()
}Обобщения позволяют писать универсальный код, который работает с любыми типами, соответствующими определенным требованиям.
func printArray<T>(items: [T]) {
for item in items {
print(item)
}
}
printArray(items: [1, 2, 3])
printArray(items: ["a", "b", "c"])UIKit и SwiftUI активно используют полиморфизм. Например,
UIView в UIKit и View в SwiftUI являются базовыми классами и протоколами, которые реализуют множество различных типов пользовательских интерфейсов.let views: [UIView] = [UILabel(), UIButton(), UIImageView()]
for view in views {
// Полиморфное использование метода addSubview()
someParentView.addSubview(view)
}
Полиморфизм используется в сочетании с Dependency Injection для предоставления различных реализаций интерфейсов или протоколов в зависимости от контекста.
protocol DataService {
func fetchData() -> String
}
class APIService: DataService {
func fetchData() -> String {
return "Data from API"
}
}
class MockService: DataService {
func fetchData() -> String {
return "Mock data"
}
}
class DataManager {
private var service: DataService
init(service: DataService) {
self.service = service
}
func getData() -> String {
return service.fetchData()
}
}
let apiManager = DataManager(service: APIService())
let mockManager = DataManager(service: MockService())
print(apiManager.getData()) // "Data from API"
print(mockManager.getData()) // "Mock data"Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
Протоколы в Swift позволяют определять методы и свойства, которые классы, структуры или перечисления должны реализовать. Они обеспечивают гибкость и полиморфизм, позволяя различным типам обрабатываться одинаковым образом.
Определение протокола
protocol Drawable {
func draw()
}Реализация протокола в классе
class Circle: Drawable {
func draw() {
print("Drawing a circle")
}
}
class Square: Drawable {
func draw() {
print("Drawing a square")
}
}Использование протоколов
let shapes: [Drawable] = [Circle(), Square()]
for shape in shapes {
shape.draw()
}
// Вывод:
// Drawing a circle
// Drawing a square
Протоколы можно расширять, добавляя методы с реализацией:
extension Drawable {
func description() -> String {
return "This is a drawable object."
}
}
class Triangle: Drawable {
func draw() {
print("Drawing a triangle")
}
}
let triangle = Triangle()
print(triangle.description()) // "This is a drawable object."Протоколы часто используются для делегирования:
protocol ButtonDelegate: AnyObject {
func didTapButton()
}
class Button {
weak var delegate: ButtonDelegate?
func tap() {
delegate?.didTapButton()
}
}
class ViewController: ButtonDelegate {
func didTapButton() {
print("Button was tapped")
}
}
let button = Button()
let viewController = ViewController()
button.delegate = viewController
button.tap() // "Button was tapped"UITableViewDataSource и UITableViewDelegate
class MyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "Row \(indexPath.row)"
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Selected row \(indexPath.row)")
}
}Custom Protocols
protocol PaymentProcessor {
func processPayment(amount: Double)
}
class PayPalProcessor: PaymentProcessor {
func processPayment(amount: Double) {
print("Processing payment of \(amount) via PayPal")
}
}
class StripeProcessor: PaymentProcessor {
func processPayment(amount: Double) {
print("Processing payment of \(amount) via Stripe")
}
}
let processors: [PaymentProcessor] = [PayPalProcessor(), StripeProcessor()]
for processor in processors {
processor.processPayment(amount: 100.0)
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM