Как стать автором
Обновить
49.43

Проектирование и рефакторинг *

Реорганизация кода

Сначала показывать
Порог рейтинга

Шаблон декомпозиции ModelView Fractal

Каждый ModelView выступает в роли модели/контроллера для ведомых ModelView и в качестве отображения для владеющего ModelView. Часть логики может выноситься как в чистые Model, так и в чистые View, которые являются лишь вырожденными случаями ModelView.

$my_user_list $my_view
	- \Owner ModelView
	users? /$my_user
	kids /
		<= Row*0 $my_user_row
			user <= user*

$my_user_row $my_card
	- \Having ModevView
	user $my_user
		avatar => image
		nickname => message

$my_card $my_view
	- \View not Model
	kids /
		<= Image $my_image
			uri <= image \about:blank
		<= Message $my_text
			text <= message \
	
$my_user $my_model
	- \Model not View
	avatar? \
	nickname? \

✅ Каждый ModelView полностью контролирует внутренние ModelView и ничего не знает про внешние.
✅ Любой ModelView может шариться между разными другими ModelView на любом уровне композиции.
✅ Изменение интерфейса ModelView требует изменения только лишь его владельцев.
✅ Фрактальная структура легко масштабируется на приложения любого размера.

Теги:
Всего голосов 7: ↑4 и ↓3+1
Комментарии0

Шаблон декомпозиции Model-View-Presenter

Модели и отображения пассивны, и не знают друг о друге - они управляются презентером, который выступает и в качестве посредника между ними.

MVP
MVP
// Presenter
class User_preview {
	user: User
	card = new Card({
		image: ()=> this.user.avatar,
		message: ()=> this.user.nickname,
		color: ()=> this.user.skin.color,
		click: ()=> this.skin_change(),
	})
	skin_change() {
		this.user.skin = Skin.random()
	}
}

// View
<div class="Card" onclick={click} style={{ background: color }}>
	<img src={ image } />
	<p>{ message }</p>
</div>

// Model
class User extends Model {
	avatar: string
	nickname: string
	skin: Skin
}

✅ Легко добавлять новые отображения, не меняя модели. И наоборот.
✅ Изменение интерфесов модели или отображения требует изменения только лишь презентеров.
❌ Трёх слоёв слишком мало на больших масштабах.
❌ Для использования состояния одного презентера из другого необходимо искусственное вынесение его в модели.

Теги:
Всего голосов 10: ↑7 и ↓3+4
Комментарии0

Шаблон декомпозиции Model-View-Controller

Контроллер создаёт отображение, и говорит ему с какой моделью работать. Так же он обрабатывает все команды от пользователя, и управляет своими подопечными.

MVC
MVC
// Controller
class Users_resource {
	GET() {
		return User.all.map( user_brief )
	}
}

// View
function user_brief( user: User ) {
	return {
		id: user.guid,
		name: user.passport.name_full,
	}
}

// Model
class User {
	
	static all = [] as User[]
	
	guid: GUID
	passports: Passport[]
	resumes: Resume[]
	
	get passport() {
		return this.passports[0]
	}
	
}

✅ Отображение может использовать произвольные модели с тем же интерфейсом.
✅ Легко добавлять новые отображения, не меняя модели. И наоборот.
❌ Для отображения разных типов моделей необходимо дублировать код отображения.
❌ Изменение интерфейса модели требует обновления всех использующих её отображений и контроллеров.
❌ Трёх слоёв слишком мало на больших масштабах.

Теги:
Всего голосов 8: ↑2 и ↓6-4
Комментарии7

Шаблон декомпозиции Model-View-ViewModel

Отображения работают с моделями через посредников, которые трансформируют абстракции предметной области в абстракции отображения и обратно. ViewModel также выступает хранилищем состояния отображения, не связанного с предметной областью.

MVVM
MVVM
// View
<li class="User_card" model="User_card_model">
	<img src={ image } />
	<p>{ message }</p>
</li>

// ViewModel
class User_card_model {
	user = User.current
	get image() {
		return this.user.avatar
	}
	get message() {
		return this.user.nickname
	}
}

// Model
class User {
	avatar: string
	nickname: string
	static current = new User
}

✅ Отображение может использовать произвольные вьюмодели.
✅ Легко добавлять новые отображения, не меняя ни модели, ни вьюмодели.
✅ Изменение интерфейса модели или отображения требует изменения только лишь вьюмодели.
✅ Одну и ту же вьюмодель можно шарить между несколькими отображениями.
❌ Для отображения разных моделей необходимо дублировать код отображения и вьюмодели.
❌ Трёх слоёв слишком мало на больших масштабах.

Теги:
Всего голосов 9: ↑6 и ↓3+3
Комментарии0

Шаблон декомпозиции View-Model

Код работы с моделями пишется прямо в отображении.

// View
function Task_list() {
	return <ul>{
		Task.list.map( task =>
			<li><Task_row {task} /></li>
		)
	}</ul>
}

// Model
class Task {
	static list = [] as Task[]
}

✅ Отображение может использовать произвольные модели.
✅ Легко добавлять новые отображения, не меняя модели.
❌ Для отображения разных моделей необходимо дублировать код отображения.
❌ Изменение интерфейса модели требует обновления всех использующих её отображений.
❌ Двух слоёв слишком мало на больших масштабах.

Теги:
Всего голосов 8: ↑4 и ↓40
Комментарии0

Do it yourself

Если видишь какое‑то несовершенство или пространство для улучшения — возьми и исправь это самостоятельно. Не нужно ждать знака свыше или того, что прилетит волшебник в голубом вертолёте и внезапно сделает хорошо.

В нашей работе много несовершенства (как и в мире вообще). Системы не идеальны, код далёк от мечты дяди Боба, процессы слегка прихрамывают. И лучшее, что можно сделать — начать понемногу убираться вокруг себя.

Жаловаться на проблемы можно бесконечно долго. Более того, жаловаться приятно — это даёт чувство собственного морального превосходства. Проблема в том, что пользы это приносит ровно ноль. Ещё ни одна жалоба не привела к улучшению ситуации.

Гораздо лучшая стратегия — замечать какие‑то недостатки вокруг себя и постепенно устранять их. Это уже сложнее. Нужно тратить свои силы и время на обнаружение, анализ и устранение проблем. Нужно брать на себя ответственность за результаты. Это занятие может быть не самым приятным, но оно приносит свои плоды.

C таким отношением к проблемам никогда не будет скучно. Ведь вокруг постоянно столько всего интересного не сделано и столько всего можно улучшить! Жизнь превращается в увлекательное приключение.

Не нужно хвататься сразу же за что‑то огромное. Сделай небольшое улучшение. Например, напиши пару тестов на проблемный код. Потом ещё одно. Потом чуть побольше. Оглянуться не успеешь, как процесс затянет.

Больше интересного про жизнь в IT у меня в ТГ

Теги:
Всего голосов 4: ↑3 и ↓1+2
Комментарии2

Шаблон декомпозиции Model-View

Модель знает как себя по разному представлять.

class User { // Model
	
	_id: bigint
	_nickname: string
	
	toString() { // View
		return 'user=' + this._id
	}
	
	toJSON() { // View
		return {
			id: String( this._id ),
			name: this._nickname,
		}
	}
	
}

✅ Удобно из модели получать любые отображения.
❌ Добавление нового отображения требует изменения модели.
❌ Отображение полностью определяется одной основной моделью.
❌ Загрузка модели вытягивает по зависимостям и все её отображения.
❌ Двух слоёв слишком мало на больших масштабах.

Теги:
Всего голосов 10: ↑6 и ↓4+2
Комментарии2

Критические расширения - классная и простая идея проектирования, которую я нашел в X.509

Расширение (не имени файла) - хороший способ сделать формат файла или протокола достаточно универсальным. Мы до сих пор пользуемся древними протоколами TCP, HTTP - потому что они расширяемы и поэтому пригодны и сейчас. В HTTP можно напихать любые хидеры, которые его создателям в страшном сне не приснились бы - и все будет работать! В идеальном мире, вы могли бы купить древнюю машинку с Win95 / Office 7.0 и открыть на нем современный документ. Да, лишившись всех новых плюшечек, но хотя бы смогли бы прочитать текст. (Жаль, разработчики Office 7.0 не читали этот пост).

Так вот, в X.509 (RFC 5280) (та самая PKI инфраструктура, на которой все держится, все вот эти вот SSL/TLS/сертификаты) тоже есть расширения. У каждого расширения - идентификатор (естественно, старые реализации не могут знать новые расширения), а еще, внимание - булевый флажок - critical. Всего 1 флаг, 1 бит, но дает огромные возможности! Мы из будущего можем сказать старой программе - либо "ты не знаешь это расширение, но не парься, просто проигнорь и обрабатывай остальное содержимое файла (или запроса) как раньше" либо же "если ты не знаешь, как обрабатывать это - даже не пытайся!". Это просто и удобнее чем версия файла-протокола (мол, если не совпадает - отказ, апгрейд, галя, отмена).

Удивительный способ, как одним битом создать канал для общения между прошлым и будущим, а ПО или устройство сделать условно вечно полезным.

Теги:
Всего голосов 5: ↑3 и ↓2+1
Комментарии1
2