Честно говоря, я не покупаю эту историю с озвучиванием рисков, и типа таким грамотным взвешиванием. Обычно к тебе приходит чувак, которому завтра нужна фича, ты говоришь что можно накостылить, но будет говно. Он спрашивает, а сколько времени если норм делать? И вот на самом деле он уже всё решил. Если срок хорошей переделки будет хотя бы на час больше, никто её не выберет. Ну и это довольно логично, ведь менеджеров не оценивают по качеству кодовой базы. Поэтому я считаю — нужно врать. Врать по разному и всё время, выкраивая себе новые и новые часы на рефакторинг. Потому что добавление фич к херовой кодовой базе её всегда ухудшает, в не зависимости от того, насколько хорошо ты эту фичу кодируешь.
В каком-то смысле мы всегда экономим на качестве, и это нормально. Итоговый код решения, которое я рефакторил — всё ещё говно. Но тут как бы есть минимально допустимый уровень. Когда мы говорим «хороший код» — имеем ввиду такой. который без большого труда может модифицировать новичок на проекте (это если мы про читабельность). Но в целом, тут конечно нет предела совершенству, если бы мне сказали, типа напиши лучший код по своему мнению, я бы пол жизни писал простейшее приложение.
Я объясняю почему я так сделал. В смысле, я не думаю, что в этой истории я хоть что-то сделал правильно, но я отлично понимаю, почему я поступал так как поступал. В следующий раз я просто бы никуда не поехал. А если бы поехал, то без жены. А если бы поехал с женой, то остановился бы у друзей. И рефакторить бы ничего не взялся, пока не попросили бы. А рассказал я про всё это, потому что из всего надо делать выводы, и не только мне.
Свобода слова про то, что тебя не могут наказывать силой закона за слова. Говорить тебе, что ты должен заткнуться могут — ведь свобода слова не только у тебя есть. Вот например внизу чувак оставил комент, в котором наоскорблял меня лично, но у него мало кармы, и я мог отклонить его комент — вот в моём понимании, если бы я отклонил — это было бы нарушение свободы слова. А принять, и сказать, что он мудила — тут всё нормально.
Не знал, что где-то существует правило, по которому я даю согласие на критику всего, что так или иначе выношу на публику. В любом случае, у других людей есть право говорить что угодно, так же как и у меня. И вот я говорю, что они, и их опыт, который они вынесли на публику — говно собачье.
Я не совсем про это. Вроде, вот такой корректный пример стейта
class SomeBase
{
public virtual string GetSomeInfo();
}
class CompleteSome : SomeBase
{
private SomeType data;
public CompleteSome(SomeType data)
{
this.data = data;
}
public void DoSomeWork()
{
//...
}
}
public class Some : SomeBase
{
public async Task<CompleteSome> Initialize()
{
var data = await SomeHeleper.Fetch();
return new CompleteSome(data);
}
}
т.е. можно вот так пользоваться:
var s = new Some();
s.GetSomeInfo();
var cs = await s.Initialize();
cs.GetSomeInfo();
cs.DoSomeWork();
Интересно, если бы я и про дочь упомянул, мне бы заодно объяснили бы, что и дочь у меня дурацкая? Статья — история, для истории важно, в каком я был состоянии. Очевидно, если бы всё было как обычно, я бы и не взвалил на себя неподъёмную задачу, а сделал бы что-то минимально необходимое.
Да, тоже хороший способ. В том коде, который я рефакторил он не подходил, потому что Some до инишиалайза мог что-то делать. Вообще я сейчас задумался. и понял что подсознательно избегаю использование фабричного метода, хрен знает почему. На ум приходит проблема с ограничением наследования
Я не столько про гарантии сколько про процесс. Вот был у меня тип A, я поменял его публичное АПИ, и получил от компилятора все места, где от этого возникли проблемы.
А насчёт тестов, обычно у говнокода тесты — такое же говно, которое ничего не проверяет.
Я немного в замешательстве. Я упомянул про жену в статье, что бы объяснить своё тогдашнее состояние, а не для того что бы узнать, что люди думают про мой брак. Видимо, это не очевидно. Поэтому я вот так прямо и скажу — мне не хочется знать чужое мнение про мою жену, и я не думаю, что это допустимо.
Такой подход гарантирует, что DoSomeWork() не будет вызван до инициализации. А проблема и так всегда была в другом месте, потому что это тут так или иначе именно клиенту придётся решать, где вызывать Initialaize
Эм, ну тут всё вроде просто.
Допустим есть класс, которому для своей работы нужно сначала сделать что-то асинхронное.
Асинхронный конструктор мы сделать не можем, вариант с неконтролируемым запуском таска внутри конструктора нас так же не устраивает.
Вот то что надо сделать — не факт что удачное.
поэтому люди иногда делают так
class Some
{
private SomeType data;
public async Task Initialize()
{
this.data = await SomeHeleper.Fetch();
}
public void DoSomeWork()
{
if (this.data != null)
{
//...
}
}
}
вот это не очень хороший подход.
Мне больше нравится такой
class CompleteSome
{
private SomeType data;
public CompleteSome(SomeType data)
{
this.data = data;
}
public void DoSomeWork()
{
//...
}
}
public class Some
{
public async Task<CompleteSome> Initialize()
{
var data = await SomeHeleper.Fetch();
return new CompleteSome(data);
}
}
А в клиентском коде мы сами решаем, какие модули у нас инициализируют этот класс, а какие уже работают с проинициализированным.
т.е. можно вот так пользоваться:
А насчёт тестов, обычно у говнокода тесты — такое же говно, которое ничего не проверяет.
Допустим есть класс, которому для своей работы нужно сначала сделать что-то асинхронное.
Асинхронный конструктор мы сделать не можем, вариант с неконтролируемым запуском таска внутри конструктора нас так же не устраивает.
Вот то что надо сделать — не факт что удачное.
поэтому люди иногда делают так
вот это не очень хороший подход.
Мне больше нравится такой
А в клиентском коде мы сами решаем, какие модули у нас инициализируют этот класс, а какие уже работают с проинициализированным.