Маркеры

Задача
Динамически, на основе фотографий из блога, формировать красивые маркеры для google map.

Анализ
В начале своей карьеры программиста, я интересовался компьютерной графикой, работой с битовыми картами, каналами и т.п.. Поэтому вариант простой реализации данной задачи сформировался еще во время постановки задачи. И заключался этот вариант в следующем – использовать готовый дизайн маркера, честно скачанный из интернета, в качестве трафарета.

Реализация
Поскольку блог работает на движке wordpress, само собой решения задачи будет выполнено на php.

Создаем класс трафарета (Stencil), в который мы будем передавать любое кропнутое в квадрат изображение, и трафарет маркера. Трафарет маркера предварительно, в графическом редакторе, приведем к одному тону, но это не будет играть существенной роли.


class Stencil {
    private $source;
    private $width;
    private $height;
    public function __construct($filename) {
        // get source image
        $this->source = imagecreatefromjpeg($filename);
        $this->width = imagesx($this->source);
        $this->height = imagesy($this->source);
    }
}

Решение работает, но еще не красиво. Для улучшение внешнего вида, нужно добавить несколько графических слове. В данном случае на нижний слой помещается изображение с тенью от маркера, а на верхний эффект глянца. Все декорации подготавливаются в графическом редакторе и сохраняются в формате PNG.

Интеграция
Для работы в контексте wordpress блога, я создал страницу с кастомными шаблоном и добавил код формирования маркера. Эта страничка вызывается 1! раз, только при условии отсутствия файла маркера, все остальные запросы на маркеры отдаются веб сервером напрямую, в моем случае через nginx.

String.Format

Классика советского кинематографа, использовать string.Format там где он уже есть в перегруженных методах.

Console.Write(String.Format("{0}{1}{2}", 1, 2, 3))

Cтроковые константы

Любимая работа программистов писать везде строковые константы.


b.GetProperty("Name");
c.Name.Replace("Name","Name");
a["Name"] = "Name";
switch(value) {
 case "Name" : return a["Name"];
}

В этом всем хаосе размазанном по всему проекту, очень сложно методом поиска и замены, рефракторить код, потому что х.з. где какой “Name”?!

Мое решение этой проблемы, вписать константы в бизнес логику класса к примеру:


class A {
  public const string Name = "NameA";
}

Легким движением new константа переопределяется:


class B : A {
  public new const string Name = "NameB";
}

Теперь строковые константы это часть бизнес логики, и по кликну на Find All Reference по A.Name я сразу получу все места применения этой константы.


switch (value) {
 case A.Name: 
  // to do ...
  break;
 case B.Name:
  // to do ...
  break;
}

Linq.Count()

Что происходит когда ты каждый раз вызываешь .Count() в пару миллионов записей.


public static int Count(this IEnumerable source) {
            if (source == null) throw Error.ArgumentNull("source");
            ICollection collectionoft = source as ICollection;
            if (collectionoft != null) return collectionoft.Count;
            ICollection collection = source as ICollection;
            if (collection != null) return collection.Count;
            int count = 0;
            using (IEnumerator e = source.GetEnumerator()) {
                checked {
                    while (e.MoveNext()) count++;
                }
            }
            return count;
        }

Nullable

Сегодня поговорим о nullable, и так int? value = 0;

Это можно юзать так:

if(value == 0){

}

А НУЖНО так:

if(value.Value == 0) {
}

Потому что во втором случае будет в раза два быстрее. Вопрос ?

Андрей: why

Афтар: Давай подумаем логически, с левой стороны у нас структура System.Nullable а с правой int, как происходит сравнение двух разных типов?!

Андрей: привидения

Афтар: не явное, да?

Андрей: ну да. Только во 2 случае value.Value == 0 разве не будет привидения?

Афтар: с лева int c права int, никакого implicit, так вот см. что делает implicit в System.Nullable


public static implicit operator Nullable(T value) {
return new Nullable(value);
}

Тадам! Оно, приводи правое значение к Nullable типу, поэтому в два раза дольше чем через свойство .Value…

Андрей: (bow)

Nullable переменную не надо проверять на null потому что это структура.


var i = val != null && val.HasValue ? val.Value : 0;

As или не as вот в чем вопрос

Забавная штука часто встречается в недрах кода.


A a = (A)GetObject();
if (a != null) {
}

Если GetObject вернет НЕ тип A то будет вам исключение в подарок, и что бы не попасть в просак без обработчика исключений лучше использовать as.


A a = GetObject() as A;
if (a != null) {
}

В любом случае код будет работать одинаково при возвращении null из GetObject

Вложенные условные операторы

Любимая тема многих программистов это вложенные условные операторы.


function foo() {
 if(true){
  if(true){
   if(true){
    return true;
   }
  }
 }
 return false;
}

Это условное дерево разрастаться до условно-дикой глубины, для восприятия кода лучше делать последовательные проверки.


function foo() {
 if(!true)
  return false;
 if(!true)
  return false;
 if(!true)
  return false;
 return true;
}

Это поможет даже при мерже кода, поскольку код разбит на логические независящие друг от дурна сегменты.