Страницы

Поиск по вопросам

вторник, 9 октября 2018 г.

Как ловить ежей в C#?

Наверное все знают о методиках ловли багов. Но мне пришла в голову мысль нельзя ли адаптировать методы ловли багов для ловли ежей? Наверняка есть какие нибудь методы или возможно кто-то уже занимался этим? Может какой нибудь особый механизм вроде try catch?


Ответ

Как известно, ежи бывают разными - лесными, ушастыми, противотанковыми и даже морскими. Все они отличаются умом, сообразительностью и коварством. То есть поймать ежа - задача не тривиальная, сопряженная с многочисленными опасностями и требующая всесторонней подготовки и современного оборудования. Именно поэтому трудно переоценить значение современных технологий в этом нелегком деле. Итак, приступим. Для начала выделим первичную сущность - Абстрактного Ежа. public abstract class AbstractHedgehog { public abstract void TellAboutItself();
public virtual void Snort() { Console.WriteLine("Пых-пых"); }
public virtual void Stomp() { Console.WriteLine("Бадабум"); }
public virtual void Fly(Human human) { Console.WriteLine(human != null ? "Я лечуууу!!!!" : "Я очень гордая птица и никуда не полечу, пока меня не пнут"); }
public bool IsCaught { get; set; } } как можно видеть, наш Абстрактный Ёж умеет топать и пыхтеть. Кроме того, современная наука установила, что с ежом также можно поговорить. Однако и это ещё не всё. Помимо всего прочего ежи умеют летать. Правда, без посторонней помощи никогда этого не делают, поэтому для полета понадобится человек. Также стоит отметить, что ёж может быть на свободе или пойман (IsCaught). В общем, наш Абстрактный Ёж может многое. Теперь подробнее о видах ежей. У нас их будет три: Ёж (обыкновенный), Ушастый Ёж и Противотанковый Ёж: public class Hedgehog : AbstractHedgehog { public override void TellAboutItself() { Console.WriteLine("Я простой ёж, и я умею пыхтеть"); } }
public class EaredHedgehog : AbstractHedgehog { public override void TellAboutItself() { Console.WriteLine("Я очень ушастый ёж"); } }
public class CzechHedgehog : AbstractHedgehog { public override void TellAboutItself() { Console.WriteLine("Я противотанковый ёж"); }
public override void Snort() { Console.WriteLine("К сожалению, я не умею пыхтеть"); }
public override void Stomp() { Console.WriteLine("Топать я тоже не умею. Печаль ;("); }
public override void Fly(Human human) { Console.WriteLine("Противотанковые ежи не умеют летать"); } } Чтобы поймать ежа, нам понадобится специальный инструмент - Ежовая Ловушка. Смоделируем ее интерфейсом - это позволит добиться определенной гибкости впоследствии): public interface IHedgehogTrap { bool Catch(AbstractHedgehog hedgehog); } Ловушки бывают разными, но все они должны уметь ловить ежа (то есть имплементить интерфейс IHedgehogTrap). Рассмотрим два вида - Простую Ежовую Ловушку (отличается невысокой надежностью и дешевизной, не способна ловить противотанковых ежей) и Усовершенствованную Атомную Ежовую Ловушку (дорога в использовании и обслуживании, но может изловить любого, даже самого хитрого и изворотливого ежа) public class SimpleTrap : IHedgehogTrap { public bool Catch(AbstractHedgehog hedgehog) { if(hedgehog is CzechHedgehog) throw new Exception("Нельзя поймать противотанкового ежа обычной ловушкой");
var random = new Random(); hedgehog.IsCaught = random.Next(2) == 1;
Console.WriteLine(hedgehog.IsCaught ? "Ёж успешно пойман" : "Коварный ёж ускользнул"); return hedgehog.IsCaught; } }
public class NucleareTrap : IHedgehogTrap { public bool Catch(AbstractHedgehog hedgehog) { hedgehog.IsCaught = true; Console.WriteLine("Ёж успешно пойман");
return true; } } Ну и последняя из рассматриваемых сущностей - Человек (он же Ловец Ёжиков): public class Human { public Human() { }
public Human(IHedgehogTrap trap) { Trap = trap; }
public IHedgehogTrap Trap { get; set; }
public void Catch(AbstractHedgehog hedgehog) { if (Trap == null) throw new Exception("Нельзя ловить ежа голыми руками");
Trap.Catch(hedgehog); }
public void Kick(AbstractHedgehog hedgehog) { hedgehog.Fly(this); } } В принципе, Человека тоже неплохо было бы сделать абстрактным, а от него наследовать несколько различных потомков, но нас ведь интересуют именно ежи, а не люди. Человек может попытаться поймать ежа (Catch), придать ему ускорение для полета (Kick), а также может иметь (или не иметь) ловушку для ловли ежа (Trap). Причем ловушка может быть любой, важно лишь чтобы она реализовывала интерфейс IHedgehogTrap - это позволяет в соответствии с паттерном "Стратегия" менять способы ловли ежа. Теперь попробуем поймать несколько ежей: public static void CatchEmAll(Human hunter, IEnumerable hedgehogs) { try { foreach (var hedgehog in hedgehogs) { hunter.Catch(hedgehog); if (hedgehog.IsCaught) { hedgehog.TellAboutItself(); hedgehog.Snort(); hedgehog.Stomp(); hunter.Kick(hedgehog); } } } catch (Exception e) { Console.WriteLine("Случилось что-то ужасное: {0}. Чип и Дейл уже спешат на помощь", e.Message); } }
....
public static void Main() { var hunter = new Human(); var hedgehogs = new AbstractHedgehog[] { new Hedgehog(), new EaredHedgehog(), new CzechHedgehog() };
CatchEmAll(hunter, hedgehogs); // {1}
hunter.Trap = new SimpleTrap(); CatchEmAll(hunter, hedgehogs); // {2}
hunter.Trap = new NucleareTrap();
CatchEmAll(hunter, hedgehogs); // {3}
Console.ReadLine(); } Как можно видеть, ежи ловились тремя способами - голыми руками , Простой Ежовой Ловушкой и Усовершенствованной Атомной Ежовой Ловушкой. Наилучшие результаты показала Усовершенствованная Атомная Ежовая Ловушка - с ее помощью были пойманы все три ежа. В заключение также стоит добавить, что в вышеописанной иерархии ежей была сознательно допущена ошибка - Противотанковый Ёж был отнесен к потомкам Абстрактного Ежа, что в итоге привело к большому количеству специальной логики в методах Snort, Stomp и Fly, и создало больше проблем, чем преимуществ. Это говорит о том, что Противотанковый Ёж должен быть исключен из этой иерархии

Комментариев нет:

Отправить комментарий