[C#] Прелести полиморфизма на примере чекера

Забаненный
Статус
Оффлайн
Регистрация
30 Июл 2016
Сообщения
267
Реакции [?]
55
Поинты[?]
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Главное ворваться

У нас есть база - солянка между всеми сервисами, и наш Василий написал такой код:
Код:
[B]public void CheckAccount(string account){[/B]
   if(account.Contains("mail.ru") && account.Contains("list.ru") && ... over9k){
           if(AuthInMail(account)
                 SaveAccount(account);
   } else if (account.Contains("yandex.ru")){
           if(AuthInYandex(account)
                 SaveAccount(account);
   }
  
   // ...
 [B]}[/B]
Все это как правило у нас впихивается в один класс, все реализации методов авторизации Yandex и прочего дерьма. Тут возможно даже еще и не такой плохой пример, некоторые индивиды бы даже не заморочились над созданием отдельных методов авторизации под сервисы, а запилили бы все в блоке if'а

Как сделать заебись или дохуя теории
Ну начнем с того что C# полностью объектно ориентирован, но почему то все предпочитают это игнорировать, а зря! Ведь многие вещи можно писать гораздо проще, логичнее и с минимальным количеством повторяющегося кода.

У нас есть такая шляпа - называется абстрактный класс. Слово абстракция вообще подразумевает собой отсутствие какой либо конкретной реализации, скорее предоставляет какую то базовую информацию о предмете в целом.

И тут можно привести в пример всеми заебаную аналогию с транспортными средствами.
Код:
[FONT=Consolas]abstract class Transport {[/FONT]
    public float Speed { get; set; }
 
    public abstract void Move(); 
[FONT=Consolas]}[/FONT]


Создать прямой экземпляр этого класса мы не можем

То есть такая шляпа не прокатит:

Код:
[FONT=Consolas]Transport myTransport = new Transport();[/FONT]


Но если мы создадим еще один класс который будет унаследован от Transport и будет содержать в себе реализацию метода передвижения, мы без проблем можем это заюзать

Код:
[FONT=Consolas]class Auto : Transport {[/FONT]
   public override void Move(){
        Console.WriteLine("хуярим на запорожце со скоростью: " + this.Speed);
   } 
[FONT=Consolas]}[/FONT]


И в добавок еще такое:
Код:
[FONT=Consolas]class Fly : Transport {[/FONT]
   public override void Move(){
        Console.WriteLine("хуярим на кукурузнике со скоростью: " + this.Speed);
   } 
}


Стоит заметить так же, что мы не определяли в классах свойство Speed, оно уже определено в абстрактном классе Transport и поэтому мы можем их без проблем использовать в дочерних классах. А юзать это можно так:
Код:
[FONT=Consolas]Transport myTransport = new Auto();[/FONT]
myTransport.Speed = 999f;
myTransport.Move();

myTransport = new Fly();
myTransport.Speed = 100f; [FONT=Consolas]myTransport.Move();[/FONT]


Суровая правда

И тут особо смекалистые наверное уже поняли к чему я клоню, эту же особенность с транспортом можно так же применить и к чекерам.

!!! Внимание, сейчас будет охуенный код !!!
Код:
[FONT=Consolas]public abstract class Service {[/FONT]    protected HttpRequest request;
   
    protected string login;
    protected string password;
    
    public abstract bool Login();  

    public static Service Parse(string rawLine){
          if(rawLine.Contains("yandex.ru")){
               return new Yandex(rawLine);
          } else if(rawLine.Contains("mail.ru")){
               return new Mail(rawLine);
          }
    }  
}


Этот абстрактный класс выполняет дофига задач, о которых вы даже возможно и не догадывались, во первых он нам предоставляет единый интерфейс авторизации для всех унаследованных от него сервисов, во вторых здесь предопределены большинство необходимых для нас полей (меньше повторяющегося кода - залог успеха мать вашу!), в третьих он нам позволяет создавать правильные экземпляры объектов в зависимости от сервиса (Знакомьтесь, паттерн проектирования - Абстрактная фабрика)

Ну а дальше дело техники:

Код:
[FONT=Consolas]public class Yandex : Service{[/FONT]
public Yandex(string line){
  //Инициализируем абстрактные поля
  request = new HttpRequest();
  //Парсинг логина-пароля
  // ...
}
public override bool Login(){
    // Реализация авторизации в яндексе
} 
}


Мы проделываем эту работу для каждого нашего сервиса
Код:
[FONT=Consolas]public class Mail : Service{[/FONT]
public Mail(string line){
  //Инициализируем абстрактные поля
  request = new HttpRequest();
  //Парсинг логина-пароля
  // ...
}
public override bool Login(){
    // Реализация авторизации в мейл ру
} 
}


А теперь вспоминаем нашу петрушку которая была в самом начале и любуемся что мы получили сейчас
Код:
[FONT=Consolas]public void CheckAccount(string account){[/FONT]
     Service service = Service.Parse(account);

     if(service.Login())
           SaveAccount(account);
 
}
 
Сверху Снизу