Уваход без разрастанне кода

Мне было цікава, калі вы ведаеце якія-небудзь лепшыя практыкі або шаблоны праектавання, так што я магу мець добрую рэгістрацыю ў маіх праграмах без іх гледзячы брудны або раздзьмутай.

Я ў цяперашні час выкарыстоўваю C# і NLog, але я мяркую, што якія-небудзь парады тут будзе мова і інструмент агностыку.

Праблема ў нас у тым, што мы хочам мець добрую рэгістрацыю, аднак мы не можам здацца, каб знайсці спосаб абысці, якое мае мноства ліній, якія проста ўвайсці аперацыі, якія могуць ператварыць просты метад, як гэта:

void Foo()
{ 
    Bar bar = dbContext().Bars.First();
    bool someCondition = bar.DoSomething();
    if (someContition)
    {
        dbContext().FooBars.Add(new FooBar());
    }
}

У чымсьці, які выглядае наступным чынам:

void Foo()
{ 
    _logger.Info("Getting first bar from database...");

    Bar bar = dbContext().Bars.First();

    _logger.Info("First bar returned from database, id = {0}", bar.Id);

    _logger.Info("Doing something on bar with id = {0}", bar.Id);
    bool someCondition = bar.DoSomething();

    _logger.Info("Something done on bar with id = {0}, response = {1}", bar.Id, someCondition);

    if (someContition)
    {
        _logger.Warn("Adding new FooBar to database");
        dbContext().FooBars.Add(new FooBar());
        _logger.Warn("Added new FooBar to database successfully");
    }
}

Вось зараз мы маем больш лесанарыхтоўчых радкоў, чым радкоў кода.

Аднак мне кажуць аперацыі, што гэты ўзровень лесанарыхтовак патрабуецца, і на дадзены момант усё яшчэ занадта грубы.

Ці ёсць спосаб абысці гэтую пачварную ручную рубку, ці я затрымаўся з ім?

38
Тое, што вы хочаце не ўваходу , <�я> аперацыі </я> на самой справе небудзь хочаце след аўдыту або <�б> падзея пошуку . Логі не надзейныя: Вы ўвайшлі «Нешта робіцца ў радку з ідэнтыфікатарам = ...» , але што, калі змены ў DbContext ж не ратаваў?
дададзена аўтар abuzittin gillifirca, крыніца
Я заўважыў UriAgassi нахільным <�я> аперацыі </я> таксама, у маім выпадку гэта было, таму што не ясна, хто <�я> аперацыі ёсць. Патрабаванні, якія паступаюць ад COO або ІТ-аперацый маюць розныя мэты, розныя рашэнні, якія датычацца іх, і яны могуць мець розныя прыярытэты.
дададзена аўтар abuzittin gillifirca, крыніца

7 адказы

Гэты выгляд пратакалявання трасіроўкі, верагодна, можа быць вырашана з дапамогай Аспект .

Аспект-арыентаванае праграмаванне дазваляе дадаць код шаблоннага стылю да вашай праграме без фактычнага напісання шаблоннага инлайн. Можна, напрыклад, дадаць аспект, чым рэгіструюцца імя метады і параметры кожны раз, калі праграма ўведзенага метаду, а затым рэгіструецца імя метады і вяртаецца значэнне кожны раз, калі метад вяртаў.

Вядома, вы не абавязкова жадаеце ўвайсці усе метад. Замест гэтага, большасць рамак аспекту дазваляюць паказаць, які код вы хочаце шаблонны дададзена.

Я не ведаю дастаткова аб C#, каб рэкамендаваць канкрэтныя рамкі аспектно-арыентаваныя на выкарыстанне, або адпаведны сінтаксіс для вас. Прабачце.

30
дададзена

Гледзячы на ​​ваш код, я лічу, што ваша праблема не толькі тое, што лесанарыхтоўчыя лініі выродлівыя, але яны рызыка ў каштаваць вам больш, чым дапамагчы вам:

  • Like comments, log line maintenance is often forgotten, and might break your code upon changes, or - worse - confuse you when trying to troubleshoot by reading the log files (think of a situation where you change Bar bar = dbContext().Bars.First();, to Bar bar = dbContext().Bars.Last();, but not changing the log files - the log will tell you that the first bar returned is X, and now you'll be scratching your head how did that happen?)
  • The logs in your code, if at all needed, are definitely not for level Info, not to talk about level Warn - these are Debug logs. Filling your files with debug logs will make your log files huge, and unusable.
    • Warn logs should be logged only when something out of the expected behavior happens, so that troubleshooting production will be focused on that.
    • Info logs should be succinct, in linear proportion to the number of transactions, and convey valuable information.
    • Debug logs are usually added ad-hoc when you are trying to hunt down an elusive bug, and need more information inside specific code. In a production scenario, these logs should be turned off.

Маюцца на ўвазе з вашага паста, што вы атрымалі гэта патрабаванне ад </аперацыя EM> каманды. У мяне цяжка зразумець, чаму каманда аперацыя дасць вам патрабаванне, каб увайсці ўнутранае паводзіны коды ... Яны могуць запатрабаваць ад вас ёсць канкрэтныя часопісы на ўзроўні функцый, але з дробназярністым каротажа патрабаванне здаецца нелагічным і не ў іх вобласці адказнасці.

Ва ўсякім выпадку, вырашыць першую кулю (і зрабіць код больш зразумела), лепшая стратэгія AFAIK выкарыстоўвае Аспект-арыентаванае праграмаванне </а >, як рэкамендаваў @BillMichell.

20
дададзена
Я згодны з вамі, ўзроўнямі я змясціў вышэй былі толькі там як частка псевдокода. Прычына для каманды АСС, якая жадае часопісы, як гэта так, што калі кліент рэгіструе выклік падтрымкі, то, як правіла, аб канкрэтным прыладзе. Гэта жаніць на ід напісана ў часопісах. Каманда падтрымкі, то проста адкрывае файлы часопісаў, фільтруе гэтым ідэнтыфікатарам, і яны, мы бачым усё, што сістэма зрабіла з гэтым элементам. Яны могуць бачыць, дзе/што апошні з ім здарылася.
дададзена аўтар user39307, крыніца
На жаль, можа быць, я павінен быў ўключыць, што гэта служба Windows. Так што на самой справе не карыстальнік. Не ведаю, калі гэта мае значэнне? Я згодны, што ён адчувае сябе няправільна.
дададзена аўтар user39307, крыніца
Я разумею іх логіку, але вы павінны сцвярджаць, што опам трэба карыстальніку <�я> актыўнасць , а не карыстальнік <�я> след . Гэты аб'ём значна вышэй ва ўзроўні і павінны ўключаць у сябе, ІМХО, у лепшым выпадку кожная кропка ўваходу карыстальнік меў (што канчатковая кропка і калі), і кожная кропка выхаду (ці было яно паспяховым, і калі не, то чаму, і, магчыма, некаторыя тэсты за колькі часу спатрэбілася)
дададзена аўтар Uri Agassi, крыніца
Я лічу, што гэта проста пытанне тэрміналогіі - замяніць «карыстальнік» з «кліентам» ці нешта, «кропка ўваходу» з «пачаткам дзейнасці», «кропка выхаду» з «канцом дзейнасці» ...
дададзена аўтар Uri Agassi, крыніца

Як Біл Мичелл адзначыў аспект арыентаванага праграмавання з'яўляецца добрым спосабам дадання кода шаблонны пратакалявання, аднак у дадзеным выпадку я не думаю, што яго сапраўды трэба - я б падысці да гэтай праблемы з некаторым добрым старамодным рэфактарынгу.

У вашым прыкладзе Foo метад робіць усё пратакаляванне, але калі гэта важна, каб увайсці, што вы збіраецеся зрабіць нешта (або што вы зрабілі нешта), то яго, верагодна, лепш, каб замест увайсці гэта ў метад, які робіць гэтую рэч замест метаду выкліку. Па рэфактарынгу базы дадзеных выклікаў у асобныя метады (якія, верагодна, варта на іншы клас у любым выпадку) і рэфактарынгу пратакаляванне выклікаў яго досыць лёгка зрабіць Foo метад так жа, як для чытання, як гэта было раней.

void Foo()
{
    Bar bar = GetFirstBar();
    bool someCondition = bar.DoSomething();
    if (someContition)
    {
        AddFooBar();
    }
}

Bar GetFirstBar()
{
    _logger.Info("Getting first bar from database...");
    return dbContext().Bars.First();
    _logger.Info("First bar returned from database, id = {0}", bar.Id);
}

void AddFooBar()
{
    _logger.Warn("Adding new FooBar to database");
    dbContext().FooBars.Add(new FooBar());
    _logger.Warn("Added new FooBar to database successfully");
}

bool DoSomething(this Bar bar)
{
    _logger.Info("Doing something on bar with id = {0}", bar.Id);
   //Implementation goes here
    _logger.Info("Something done on bar with id = {0}, response = {1}", bar.
    Id, someCondition);
}

Такім чынам, у адказ на больш агульнае пытанне «Як дадаць ўваход, захоўваючы пры гэтым кода для чытання?», Я рэарганізаваць свае метады на больш дробныя метады, пакуль кожны метад не чытаны, як гэта павінна быць.

9
дададзена
Так, гэта. Але ў ідэале абодва. Кожны метад, які загружае аб'ект з ідэнтыфікатара павінен увайсці ў тую ж інфармацыю: ID = х, знойдзена у. Гэта павінна прымяняцца паслядоўна ва ўсіх суб'ектах. Пасля таго, як вы зробіце гэта, вы можаце выдаліць чатыры радкі пратакалявання з метадаў кліента і скараціць код базы значна.
дададзена аўтар slipsec, крыніца

Уваход калі вы збіраецеся зрабіць што-небудзь ці калі нешта ідзе правільна добрыя для кода развіцця. Падчас распрацоўкі, вы хочаце ведаць драбнюткія падрабязнасці таго, што адбываецца.

У вытворчым кодзе, вы чакаеце, што ўсё будзе добра. На самай справе, у ідэале вы хочаце толькі атрымліваць інфармацыю, калі нешта ідзе не так: Вы атрымліваеце выключэнне з кода, выклік базы дадзеных не можа ці важная частка вашага кода вяртае нешта нечаканае. У тых выпадках, вы хочаце, каб увайсці, што пайшло не так, і, калі гэта магчыма рэгістраваць зменныя вы працуеце з, каб дапамагчы прайграць памылку.

У прыведзеным вышэй выпадку, вы не хочаце рэгістравацца кожны раз, калі вы атрымліваеце Бар, ці што ў вас ёсць панэль з ідэнтыфікатарам X, ці што вы робіце нешта на бары, або што вы паспяхова зрабілі нешта на панэлі. Вы чакаеце, што тыя, каб працаваць належным чынам, так што вы толькі хочаце, каб увайсці, калі нешта пайшло не так там, а затым увядзіце тэкст штрыхавыя зменныя, якія выкарыстоўваюцца ў йоЗотеЬЫпд() і ID бара. Калі someCondition дакладна, вы хочаце, каб увайсці, што вы дадалі нешта, але вы не хочаце рэгістравацца, што гэта атрымалася, толькі калі яно пайшло не так.

Калі аперацыі кажуць, што яны сапраўды патрэбныя гэта лесасечнага заяву, яны чытаюць гэта няправільна. Яны не хочуць гэта лесасечнага заявы, яны хочуць ІНФАРМАЦЫЮ гэтых лесасечныя заяў генераваць. Яны, верагодна, хочуць статыстыкі, заснаваныя на гэтых лесанарыхтовак заяў, ці нешта звязаныя з заявамі лесанарыхтовак. Абмяркуйце з Шэфам, чаму яны маюць патрэбу ў гэтых заявах і даць ім тое, што ім трэба.

6
дададзена

Як і іншыя тут паказалі каротажа нясе тую ж нагрузку, як каментары - занадта шмат ці занадта мала прыносіць больш шкоды, чым карысці.

Адзін практычны падыход да палягання, каб змясціць радок увайсці найбольш ключ галіны - некаторыя галіны робяць нязначныя рэчы і не варта рэгістрацыі. Найбольш крытычная галіна для ўваходу з'яўляецца злавіць (Exception х) - заўсёды выключэння аўтарызуйцеся

Што ж тычыцца зместу часопісаў у мяне ёсць некалькі з унікальнага падыходу: Я стварыў для надбудовы маіх любімых асяроддзяў распрацоўкі (VS, Eclipse) вынікае, што пры націску гарачай клавішы ўставіць кароткую унікальную закадаваную паслядоўнасць знакаў зададзенай даўжыні (10 літар, усё прапісныя) і я выкарыстоўваю гэтыя + час выканання дадзеных замест чытэльным verbage.

Я называю гэтую «debrix коду», і яны маюць мноства пераваг, некаторыя з якіх:

  • ня брудны складаныя фармулёўкі
  • Вы можаце заўсёды знайсці месца ў кодзе, які вырабіў пэўны часопіс
  • Вы можаце лёгка падлічыць асобнікі канкрэтнага паведамленні або іншыя статыстычныя дадзеныя: у мяне ёсць LINQPad скрыпты, якія маюць імя файла часопіса і debrix Код для атрымання здымкаў паблізу кожнае ўваходжанне
  • Пры выкарыстанні толькі дадзеных у час выканання вы можаце быць упэўнены, што ваша паведамленне заўсёды актуальны: калі аб'ект перапрацаваны з вас вымушаныя рэарганізаваць паведамленне часопіса, а таксама.
  • унікальныя коды debrix па ўсёй складанай сістэме з некалькімі платформамі будзе па-ранейшаму прывядзе вас да аднаго месца, якое зрабіла часопіс паведамленне, незалежна ад таго, гэта JavaScript, на боку сервера, на баку кліента (OSX Пражэктар вельмі зручна)
  • код можа быць уключаны з кліенцкімі бачнымі паведамленнямі пра памылкі для падтрымкі кліентаў. Нароўні з пазнакай часу гэта ўсё, але гарантавана адназначна ідэнтыфікаваць падзея

Гэта, як я хацеў бы выкарыстаць гэты падыход, каб увайсці ваш ўзор кода:

void Foo()
{ 
  try{
    log.I("[FFASREQEKT]"); 
    Bar bar = dbContext().Bars.First();

    bool someCondition = bar.DoSomething();

    if (someContition)
    {
        log.I("[FFGFAJNNBGB]"); 
        dbContext().FooBars.Add(new FooBar());
    }
  } catch (Exception x){
   //This catch is only for illustrative purpose. In real code it may be outside this method
    log.E("[FFGADJNANQ]", x);  
  }
}

Гэта дазваляе мець поўнае ўяўленне, якой код шлях быў узяты з найменшай колькасцю паведамленняў.

2
дададзена
+1 Гэта выдатная ідэя. Я бяру вялікія намаганні, каб паведамленні часопіса ўдакладненага, часта шляхам стварэння тыпізаваных метадаў для забеспячэння выканання семантыкі. Але выкарыстанне унікальнага кода спалучэння робіць фільтрацыю ветру.
дададзена аўтар slipsec, крыніца
Ці з'яўляецца ваша «кода debrix» - «надбудова» для зацьмення дзе бясплатна спампаваць?
дададзена аўтар Freda, крыніца
Гэта баночка для Eclipse, гэта груба вакол краёў, таму што я ў асноўным выкарыстоўваць VS, і ўстаноўка па эксплуатацыі dropbox.com/s/oxx9efxhhh0n8ih/AidemaDebrix_1.0.0.6.jar | Навучальны дапаможнік для зацьмення: help.eclipse.org/indigo/…
дададзена аўтар Ella, крыніца
А вось надбудова ўсталёўнік VS, пратэставаны на VS2008-2012: dropbox.com/s/idgvodomej1gbrk /VisualDebrixSetup.msi
дададзена аўтар Ella, крыніца
@DavidHarkness убудова VisualDebrix фактычна займае верхнія літары ад імя бягучага файла ў якасці прэфікса для ўсяго кода, такім чынам, паведамленні, атрыманыя ў рамках аднаго класа маюць адзін і той жа прэфікс і «выпадковы» код на самай справе дае вам невыпадковы ключ. Карысна для чытання суседніх паведамленняў часопіса
дададзена аўтар Ella, крыніца

На ўзроўні ўваходу вы апісваеце адладчык, здаецца, значна больш разумным. Кажучы па меншай меры, для сябе і майго падмосці мы будзем выкарыстоўваць пратакаляванне двух спосабаў.

  • Агульныя INFO і аднарангавыя DEBUG пратакаляванне ўзроўню, які давайце адзін след памылка ў пэўнай часткі прыкладання і даць мета-дадзеныя, такія як ідэнтыфікатар 's і аналагічная інфармацыя.
  • А па-другое пратакаляванне дарослых (карыстацкіх) дзеянняў, каб зрабіць магчымым, каб убачыць тое, што зрабіў менавіта карыстальнік (як для выпраўлення памылак, або калі кліент мае прэтэнзіі, што ён зрабіў што-то два месяцы таму, нібыта не працаваў).

Затым адладчык можа быць выкарыстаны, каб прайсці праз код парадкова, даючы ўсё больш падрабязную інфармацыю аб тым, што вы ўваходзіце ў цяперашні час, не ўсе відавочныя радкі часопіса апісання таго, што адбываецца (што, у выпадку неабходнасці будзе ў каментарах, а не часопісы ).

1
дададзена

Можа быць, для вашага канкрэтнага прыкладу можа быць карысным, каб атрымаць падклас DbContext (скажам, loggedDBContext), які абгортвае гэта метады з кодам, часопісы ўсё, што вам трэба, і затым выконвае «сапраўднага» метаду. Даданне/выдаленне пратакаляванне затым будзе складацца ў выбары выкарыстання DbContext супраць loggedDBContext у канструктару (ці завод), але нічога не мяняецца.

У некаторых мовах ёсць спосабы ін'екцыйных такіх аспектаў, непасрэдна ў функцыях - змяніць свае паводзіны, не патрабуючы код выкліку нават ведаць, што функцыі змяніліся, і цяпер таксама пратакаляванне; але я не ўпэўнены, калі гэта можа быць зроблена ў C# без відавочных падкласаў.

1
дададзена