Визначаємо вартість декоратора в Golang
Привіт, мене звати Ярослав, займаюсь розробкою сервісу для збереження активів у криптовалюті в компанії ITAdviser, розробляємо на Go. У цій статті розглянемо декоратор, його вартість і чи варто використовувати його в розробці нових сервісів.
Коротко про мене
Кілька років тому почав цікавитись Go, подарував другу на день народження книжку «The Go Programming Language», сам грався задачами з LeetCode, облишив, через півроку продовжив, вийшов професійний курс від «Техносфери», передивився і цього було достатньо, щоб почати працювати як Junior Go.
Go зацікавив тестами та бенчмарками з коробки, можливістю розбиратись в коді стандартних бібліотек, які теж написані на Go. А ще в Києві хороше Go ком’юніті. В деяких мовах рішення певних задач лаконічніше та красивіше, ніж в інших. Уже вкотре зустрічаю теми, де автори описують, як бачать ідеальну мову програмування, а інші ж створюють такі мови, прикладу Ruby.
Що таке декоратор
Так, в Go зручно реалізувати патерн декоратор. Це відомий патерн, вже описаний в книжці Gang of Four «Design Patterns: Elements of Reusable Object-Oriented Software» (та початківцям краще починати з «Head First Design Patterns»).
Декоратор зручний, коли треба розширити функціональність без змін компонентів. Мені він нагадує матрьошку, якій треба розмалювати іншим кольором руки. Беремо матрьошку, обертаємо її в прозору плівку, розмальовуємо руки, плівка та малюнок і будуть декоратором. Шрек приводив у приклад цибулю.
В основному проекті ми використовуємо декорацію для запису в журнал взаємодії через API клієнти та для синхронізації.
Дуже просто покрити тестами основну логіку, а всі додаткові обгортки винести в декорацію. Але перед тим як так структурувати частину проекта через декоратори, треба довести, що його вартість мала.
Реалізація
В Go реалізувати декоратор простіше, ніж через ООП. Візьмемо штучний приклад класу на PHP з двома методами. Один треба змінити, а інший залишити, як є:
interface GeneratorInterface
{
    public function increment(int $step): int;
    public function stats(): Stats;
}
class GeneratorIncrementDecorator implements GeneratorInterface
{
    private $source;
    private $coefficient;
    public function __construct(GeneratorInterface $source, int $coefficient)
    {
        $this->source = $source;
        $this->coefficient = $coefficient;
    }
    public function increment(int $step): int
    {
        // decorated
        return $this->source->increment($step * $this->coefficient);
    }
    public function stats(): Stats
    {
        // as is
        return $this->source->stats();
    }
}
class Stats{}
А тепер на Go:
type Generator interface {
	Increment(step int) int
	Stats() Stats
}
type GeneratorIncrementDecorator struct {
	Generator
	coefficient int
}
func NewGeneratorIncrementDecorator(source Generator, coefficient int) Generator {
	return GeneratorIncrementDecorator{
		Generator:   source,
		coefficient: coefficient,
	}
}
func (d GeneratorIncrementDecorator) Increment(step int) int {
	return d.Generator.Increment(step * d.coefficient)
}
type Stats struct{}
В Go декоруємо тільки потрібний метод, а метод Stats вбудовується. В офіційній документацій це називається Embedding. В PHP, як і в Java та C#, треба буде обгортати усі методи.
А тепер приклад, щоб визначити вартість. Візьмемо структуру з однаковими функціями.
    type (
        source interface {
            increment(int) int
            wrap(int) int
            proxy(int) int
            same(int) int
        }
        handler struct {
        }
    )
    func (handler) increment(s int) int {
        return s + 1
    }
    func (handler) wrap(s int) int {
        return s + 1
    }
    func (handler) proxy(s int) int {
        return s + 1
    }
    func (handler) same(s int) int {
        return s + 1
    }
Продекоруємо її різними методами:
    type (
        decorator struct {
            source
        }
    )
    func newDecorator(source source) source {
        return decorator
    }
    func (d decorator) increment(s int) int {
        return d.source.increment(s) + 1
    }
    func (d decorator) wrap(s int) int {
        return d.source.wrap(s + 1)
    }
    func (d decorator) proxy(s int) int {
        return d.source.proxy(s)
    }
    // embedding
    //func (d decorator) same(s int) int {
    //	return d.source.same(s)
    //} 
 
Додамо benchmark на кожну функцію інтерфейсу та допоміжну тестову функцію, щоб декорувати N разів: 
 
    import "testing"
    const N = 127
    func BenchmarkSource(b *testing.B) {
        handler := handler{}
        for i := 0; i 
					  
					 Похожие статьи:
					   
							 
							   
							   Xiaomi – производитель смартфонов номер 1 в КитаеНесмотря на то, что компания Xiaomi не смогла достичь прогнозируемого производства смартфонов за год, по данным Wall Street Journal, ей удалось...
						
							 
							   
							   В Україні планують погодити «єБронювання». Як зміниться механізм та за яких умов працівникам відмовлятимуть у броніКабінет міністрів планує розглянути постанову про «єБронювання». Цей документ визначатиме, як компаніям подавати й погоджувати...
						
							 
							   
							   В якій країні менші податки для айтівців і як не платити двічі за кордоном – розбираємось з консультантомУ цьому відео розбираємось з податками айтівців в Україні під час війни, як і де платити менше податків в Європі, уникнути...
						
							 
							   
							   По 10 января в российских магазинах – снижение цены на PlayStation 4, комплекты и игрыКомпания Sony Computer Entertainment Europe объявила о существенном снижении цен на PS4 и ряд популярных игр для нее – только с 14 декабря по...
						
							 
							   
							   Что послушать: обзор англоязычных IT-подкастовНесколько месяцев назад мы публиковали подборку русскоязычных подкастов, посвященных IT. Напомним, подкаст — это серия...
						
				
		
	
						
						
				
				
				
								
		Последние материалы	+21% вакансій | Зарплати стоять | Маркетинг в топі   +21% вакансій | Зарплати стоять | Маркетинг в топі   +21% вакансій | Зарплати стоять | Маркетинг в топі   Американський стартап Fireworks AI залучив $250 млн інвестицій. Серед його засновників — двоє українців  Майже кожна п’ята відповідь ШІ про війну в Україні містить роспропаганду. Хто цитує найчастіше  		
			Анализ сайта
Яндекс директ
Аудит сайта
Оптимизация
Seo новости
Продвижение ( Статьи )
Новости IT
		
		Советуем почитать	 
{source}