好 你们好吗 这是一个评论您需要查看一个设计基于您的评论就是JavaScript 或者其他我选了JavaScript的评论在之前的谈论中很多人使用了JavaScript您可以谈论水水哇 你买新的电脑了没有公司公司 公司 公司 公司不错 不错 不错好 这点福利还是不错呵呵呵您需要查看一个评论吗好您可以查看一个设计基于您的评论谢谢谢谢JavaScript您可以谈论水水您可以谈论水水您可以谈论水水您可以谈论水水您可以谈论水您可以谈论水水您可以谈论水水您可以谈论水水您可以谈论水水您准备好了吗要开始吗您也想谈论水水您有机会吗好的开始谢谢大家都今天会训练 try code cutterCode Cata together to refactor some of the Lexi code baseOK,let's start itSo what is code Cata?So for those who attended the previous sessionsCan someone remember what is code Cata?Any volunteer?OK,don't be too shySo this is a term coined by this gentleman called Dave ThomasHe take a metaphor from those who practice martial artsSo for those like the practicing martial artsThey usually practice a lot of basic movesAgain again and with the purpose to build their muscle memorySo that during the real comeback or fightIf they want to make a sidekick or make a punchThey can take the action right awayWithout thinking about oh how should I take this actionSo similarly for developersThere are many basic skills that we need to masterAnd we should do exercise regularlySo that those things become part of our muscle memorySo that during the real workIf you have a problem to solveThen you can take those actions quicklyWithout thinking about oh how should I do itSo it's just my ideaAnd today we are going to do a CataWhere you are going to practice your code refactoring skillsSo the Cata is a bit specialBecause you need to deal with some of the Lexi codeThen does anyone know what is Lexi code?Very oldOK,that's one definitionAny other definition?What is Lexi?SorryYes,it sounds code that you take over from other peopleThat's also a possible definitionBut actually one of the definition I heard isLexi code are the code that you check into your code repositoryProbably not by youYou other people is already in the code repositoryAnd even just the code that was written a second agoAs long as they already checked into the code repositoryThey become Lexi codeNo matter whether those codes are written by you or notWhether those codes are having good quality or notAs long as they are there,they are Lexi codeThey are both assessThey are also your liabilitySo you need to make sure that you maintain those codes wellAnd for those who are interestedHow to work with Lexi codeThis is a classic book in this industryWalking effectivelyWalking effectively with Lexi codeSo it basically give you some of the ideaOr good suggestions on how you can deal with Lexi code baseYou can take a rate if you are interestedBut for today,I'm going to give you a fewVery quick pointers and then we can do some exerciseAnd then another questionWhat is refactoring?This should be an easy oneImproveYes,what to improve?CleaningI hear thisIt's similar to thatSo what is refactoring?Refactoring is basically to clean up your codeOr to make some improvements to your code baseSo typically you will haveI guess it's very common for youTo look at this kind of code baseIn your own work,either written by yourselfOr by other peopleIt's a long methodIt's a lot of variable namesSo not very clearAnd probably very confusing logicHere and thereAnd you need to scratch your headTo figure out what it doesSo typically you will see this code baseAnd then as a good developerWhat you should try to doIs to improve the code qualityAnd make it cleanerOr then that activity is called refactoringSo refactoring is basicallyTo improve the designOr implementation of the existing codeWithout changing its behaviorSo thisThe book title didn't really mention this partBut it's very importantTo remember thatFor refactoringYou are not supposed to change the behaviorOf the codeYou are just improving the designOr implementationBut you should keep the existing behaviorAnd in case there are indeed bugsYou solveOr there are behaviorsYou need to improveThen take that as enhancementTo your systemAnd they are separateThey should be separate tasksFrom the refactoring taskOkayLet's also quickly mentionA few challengesAbout the lexical baseSo one challengeOf course is the convoluted codesTypically those lexicalsAre most likely writtenBy someone beforeAnd the person probablyAlready left the teamAnd then whateverHe left with youIs a bunch of codesAnd you read the codesYou still couldn't understandWhat exactly does the code doI guess many of you are notNew to this kind of challengesAnother possible challengeThere is no documentationThere is no specificationOr whateverTo tell youWhat the code is supposed to doThis brings a huge challengeWhenever you are supposed to be the oneMaking further changes to the codeAnd how do you knowThat you are keepingThe existing behavior or notDocumentation or specificationHow do you knowThat you are not breakingAnything that is already workingSo this is a challengeNow the next challengeVery commonYou do not have any test caseFor the codes that you getAnd this brings a challengeBecause just nowWe were talking about refactoringWhich is supposed to beThe activity for you to takeIn order to improveThe quality of the systemBut you can't do refactoringWithout test casesWithout any test casesSupposed to be changing the codeHow do you knowThat you are not breakingThe existing behaviorSo the test cases are importantAnd unfortunatelyIn many lexical debatesYou do not have themAnd another possible challengeEven if you are brave enoughYou decided toLet's add some test casesTo this systemSo that I can do some refactoringBut you will realizeThat it's very hardMany cases it's very hardTo add test casesBecause when the originalDevelopers wrote this piece of codeThey probably didn't really thinkFrom the angle of making it testableAs a resultWhen you decide to test itYou will find out thatOh, it's hard to testLike the code may have a lotOf dependencies on other modulesAnd in order to testThis piece of codeYou need to get another module runningYou need to getSome other existing systemTo be runningAnd it probably also dependsOn some databaseTo be some recross setupFor you in order to runYour test caseSo all those dependenciesMakes the testingA lot difficultThen it should beSo all thisJust becauseWhen you areImplementing the codeYou didn't reallyThink aboutHow to write test casesSo this is alsoA typical challengeFrom the lexical baseThen as a developerWhat should we doWhen we get those codebaseSo todayWe are going toLearn some of the simple tipsAnd then quicklyGet our hands dirtyBy do some refactoringUsing those tipsSo the oneOne of the major tipsThat I'm going to introduce todayIs called theCharacterization testSometimes people also call themGolden master testHave anyone heard about this term beforeCoolI can introduce this one to youSo it's actuallyNot hard to understandAnd actually youProbably already experiencedThis kind of thingIn your real lifeNot as a developerBut for exampleThere is a young ladyHe is looking forMr.RightHe just get to knowA new gentlemanAnd started datingAnd then this ladyIn order to testWhether this gentlemanIs the Mr.Right or notHow would she knowRightSo what she can doIs toPull this gentlemanUnder different scenariosAnd look atHow he behaveHow he speakHow he actAnd how he reactTo differentDifficult challengesOr questionsLike if meAnd your motherWe both fell into the riverWho do you say firstRightSo those areThe type of questionsYou probablySome of you got askedAnd those areSo-calledCharacterization testSo they just want toLike to throw you intoThose questionsAnd see how you behaveAnd thenIn this caseThe young ladyGet better understandingOf the characteristicsOf this gentlemanWhether they fit or notRightSo this isCharacterizationCharacterization testIn the real lifeSo as a developerWe can do similar thingsWhen you getWhen you getWhen you getOur new code baseOur systemThat you're not familiar withAnd you're supposedTo do somethingDo some changesWith this systemThe first thingYou can doIs toObserveHow the systemBehaveUse whatever you canYou can run the programLook at the UILook at the logWhateverAnd try to observeHow it worksAnd actuallyWhen youObserve how it worksYou canActuallyPut those knowledgeInto test casesEspecially theAutomated test casesSo those areThe basicallyCharacterization testTalking aboutSo those test casesEventuallyThey willBecome a safety netOnce you haveEnough test casesThen those test casesWill protect youWhen you makeFurther changesTo the systemThen they can easily tellYouHow to changeThe behaviorOf the systemSo this isThe purposeOf theCharacterization testThere are two waysTo writeThose test casesDepending onThe qualityOf the systemThat you're dealing withSo if you're luckyThe code baseIs actuallyNot that badAnd it's possibleTo writeSome unit testTo understandHow the systemBehavesSo in that caseThe modelOr the unitYou are going to testCan be isolatedFrom the restOf the systemOr model or componentsAs long asYou can isolate thisUnder your test harnessThen it's possibleFor you toWrite some test casesTo exerciseHis behaviorAnd if you'reLucky enoughYou can even writeUnit testTo assertWhat the system doesBut the wayOf writingThis kind of test casesIs a bit differentFrom whatWe showed you beforeIn the first sessionThe test-drivenDevelopmentWhere you'reBasically writingA test caseTo assertYour expectationWhat you expectThe systemTo behaveSo at that timeYou're supposedTo knowWhat the expectationIsSo you startWith a test caseAnd thenYou do the implementationBut in this caseYou have a Lexi systemYou don't really knowHow the systemShould behaveThen howAre you supposedTo writeThis test caseSo I haveClickThe linkSo this blogIs fromThe author ofThe bookI showed you just nowI think his nameIs calledMichaelMichaelphysusHe probablyIs a bad personThat understandsAll these termsHe wrote theBlog articleAnd whatIs theCharacterization testAnd so hereMaybe let meJust enlargeThe phone a bitSo thisIs a functionThat he's tryingTo testAnd justTo give a quick glanceAt this functionI thought anybodyCan quickly figure outWhat this functionShould be doingWith in one minuteIs hard to understandWhat it is doingAnd soAs youIf you want to doFurther changeOn this functionThe first thingYou can doLet's writeSome unit testOn this functionTry to understandWhat the function doesAnd the sequenceOf the test caseFirstlyYou writeA test case like thisVery simpleYou just seeI call this functionI pass in this inputAnd I'mTrying to assertWhat is the outputBut becauseI'm writing this testI don't really knowWhat is the behaviorOf the systemSo I don't careSo I just putA now hereWhatever valueYou can put it hereAnd thenThis is first stepSecond stepYou need to runA test caseMost of the time100%It would failBecause you're just randomlyPutting our expectation thereAnd you don't really knowWhat's the right behaviorVery possibleThe code would justFail like thisSo the outputOf this functionIs so-calledPlantaxBut thenYou are assertingThat this value should be nowAnd by looking atThis messageYou know thatMy original expectationWas wrongAnd the real behaviorOf the systemIs wheneverI gave this systemA plain text stringThe systemOr ratherThis functionWill return meA plain textSo nowYou through thisTask caseYou start to understandHow the systemOr howThis functionBehaveYou got the punchYou write a test caseJust give itGive the functionSome inputAnd thenThrough theRunning the test caseYou get the realReturnFrom that functionAnd through thisYou learnedHow that functionShould workAnd this particular scenarioThenWhat you should doIs updating a test caseUpdating a test caseBasically to recordThis behaviorSo in a wayThis test caseBasically isAutomated recordTo sayFor nowAs far as I knowThis system behavesIn this wayAnd you'd betterChange the nameOf the test caseTo make it descriptiveTo basicallyDescribeThis behaviorVery wellSo just repeatThree stepsFirst stepNo for sureIt will failAnd second stepRun the test caseAnd observeWhat is the realReturnWhat is the realBehaviorOf the systemThird stepRecord on thisBehaviorIn your test caseAnd thenRepeat this stepTo getYour second testCase, et ceteraSo after some timeYou will accumulateA set ofTest casesThose test casesBasicallyThe automated test casesThat describeHow theCurrentlyTest casesAre calledThe characterisation testBecause they are usedFor you toBuild upYour knowledgeAnd howThis system should workAny questionsIs it right?So is it right to sayThat you are usingThe unit test hereMore for reverseEngineeringAnd less for testingTo recordYou are trying to understandHow it is to travelAnd not to testSo the question isSo the question wasFor this kind of testingIs it rightThat we are actuallyDoing some kind ofReverse engineeringInstead ofTesting howThe system worksTo some extentYesBecauseI don't thinkWe should useThe term reverseEngineeringBecause that'sTypically relatedTo become powerSome bannersAnd then figureOut the source codeEt ceteraThe term hereI would likeThis test casesAre for youTo understandLearnThe behaviorOf theThe systemAnd onceYou have this test casesFor nowIt's used for youTo learn the behaviorAnd onceYou have those test casesAnd you keep running themThen they willBecome yourSafe net to protect youWhenever you makeFurther changesOkaySo this is one wayWhere you canGenerateThe automated test casesSo this is another waySo this is a new slideI'm going to showThere's actually another waySo thisThe second one isIn the situationWhen you areNot luckyThe systemThat you gotBasicallyIt's just like aSystem by itselfIt's very hardFor you toDecouple itOr isolate anyModule for youTo do the unit testThen as a resultYou have toTest the whole systemIn one goAnd in this caseYour test casesProbably shouldn't be calledUnit test anymoreUnless you reallyTreated the whole systemAs a unitBut otherwiseIt should be treatedAs a system testBecause you're testingThe whole systemIn one goAnd also becauseIn this caseUnlike a functionIt's not easyFor you toGet some return valueFrom the systemAnd usuallyThe practice isThe system needsTo have some kind ofUIWhere you can getThe output from the UIOr the systemOr havingSome logsEither to the consoleOr to the fileAnd you can observeThe system behaviorBy checking outThe logsSo thoseIn those situationsWhat you need to doIs firstlyYou need to redirectAll those logsInto a fileSo that you canCollectAnd secondlyYou need to find outFor the systemWhat are the possibleInputsGiven thatAll the possible scenariosYou knowWhat are the possibleInputsJust runThe systemAnd all thosePossible inputsAnd thenFor each possibleScenarioYou collectSome log filesFor exampleAnd thenThat log filesBasically capturesAll the behaviorOf how the systemBehavesAnd thenOnce youHave the collectionOf those log filesYou canIt's possibleFor youTo write someTask casesAnd basicallyRun the programAgainAnd forEach timeYou justCompareThe latestOutputYou getWith the outputThat you collectedBeforeAnd to justTo checkWhetherThey match or notLet's imagineThat you canGenerate1,000OutputsWhich recordDownHow the systemBehaves right nowThenLaterWheneverYou runYour systemYou justYourOutputWould changeAnd thenYou willFind outSome discrepancyWhen you compareThe latestOutputAnd theOutputYou recordIn thisSo-calledGolden master testThenThat helps youTo captureAny possibleBugsYou introduceWhichChangesThe behaviorOf the systemSoThose recordsThere's a nameGolden masterGolden master testSoBasicallyThoseGolden mastersWhichSupposed to beThe oneThat capturesHow your systemShould workAnd thenBy rightYou should notDevateFrom those behaviorsUnlessYou knowExactlyThat's a bugThat's a behaviorThat youWould like to changeOtherwiseThose behaviorsAre thereTo helpOkaySoFor this oneI will show youHow I useThis techniqueTo tackleThe problemWe are trying to solve todaySo theUgly codebaseWe are going toDevate todayIs calledThe ugly triviaSoThis isBasicallySimplifiedAlsoUgly-fiedGameOfWhat you can see是IIIIIIIIIIIIIIIIIIIIIIIIIIII比如说 about sports, about music, about the geography, whatever.所以, when you answer the questions, if you answer it right,you'll probably win some talking or reward,and then if you win enough talking,let's say you win the six talking or calling,then you're the winner. Otherwise, if you answer the question wrongly,you could also be punished,like you could be put into some kind of the penalty box,你不允许接下来等等这些是一种游戏你可以玩在这一部分所以我们今天会用的筹码是最美与其他语言的筹码可以看到的首先,因为我们的筹码我们需要明白它 first我们会用筹码然后我们可以认识筹码的筹码明白它然后我们也会认识筹码的筹码我们可以评论一些筹码的筹码我们可以在筹码中处理然后我会试试我们可以建立金牌试试的筹码我会试试解释的筹码我会试试解释解释的筹码但再次,用其他语言可以做一些相似的事情然后我会给你一个简单试试如何去解释筹码然后,希望我们将会有足够的时间大家可以用手势去解释筹码的筹码让我试试筹码的筹码是的,所以,现在如果你查看筹码在码上分享的筹码用了java script这个筹码是非常简单的这里有Main.js,就是进入评论可以转发这个订阅还有另外一个评论叫做GimRunner它叫Main.js它开始游戏建议一些游戏然后,就转发游戏用筹码的筹码让游戏的评论等到有赢这就是GimRunner实际的游戏在这个游戏.js是,你看到这些非常厉害的评论看了不少的评论可以看见它有多大的功能也有很多的评论这是我们今天试试的主要评论我们开始的第一步就是转发订阅看看它有多多的功能好,让我转发订阅我们可以转发在订阅好,让我转发订阅好,我可以转发订阅by justrunningman.js大家是GimRunner大家是GimRunner大家是GimRunner大家是GimRunner大家是GimRunner大家是GimRunner好,那么,这一步我们用GimRunner但,这些评论是同样的评论也许,这些评论是同样的评论所以,我可以转发如果大家转发订阅在订阅阅您会看到一些评论让我们评论这些评论看看它在做什么首先第一个是我们的评论它有一个计算是第一个然后,两个计算他们的评论他们有自己的评论然后,Chet是第一个评论他写了评论然后,这位评论将他的评论转发到第六位然后,他有一个问题在评论中然后,他第一个问题从评论中然后,他他得到评论然后,他得到一块鸿然后,Pat成为第二个评论他得到第四个评论然后,他移动了他的评论第四个评论然后,他开始回答他的评论是他得到不同的评论然后,他发出评论然后,他的评论他的评论是第一个评论他的评论也是对的然后,他得到一块鸿所以,你可以看到就像我刚才所说的每个评论中的评论每个评论中的评论每个评论中的评论几个评论然后,他他可能得到一个评论如果始终有一次他会得到一个评论然后,他可以学会 LegalBolicenne然后,他必须要学会找其他评论对,我...它动药压�对,那么张昌那 Butter他唸然后她没有回答对方的问题然后她发送到手机箱里后来,我认为 next time when Su got her 10她是一个现场的球员她必须承担然后,总之,有些计划她正在选择,根据这些计划她知道她是否得到奸詐的奸詐總之,我們仍然不知有些邏輯因此,她是否得到奸詐的奸詐如果她沒有得到奸詐的奸詐就覺得她已經失敗了她的機會她會回答問題所以她不可以回答問題了然後,下一位球員會來參賽這似乎是個個案如果有人得到六個奸詐那會有一個勝出然後,會有一個勝出就是這個奸詐的奸詐所以,在這次的課程中我們可以在這次的課程中有很高級的理解我們可以在這次的課程中當然,我們仍然沒有有些迷惑的邏輯我們並沒有認識我們要知道如何決定如果有人會得到六個奸詐的奸詐我們也不知道但,我們只要看這次的課程我們並沒有認識所以,我們仍然需要看同一奸詐所以,剛剛講到真正的根據是在這次的遊戲中它們所進行的這奸詐的根據我們需要知道就先看這奸詐可以給這位球員解釋一下我們所觀看的問題包括這次的課程中首先,我看到的是,这个 Code 用了一些 Lexi 技术的功能例如 RAR 技术如果您 familiar with 技术在最新的 ES6 用了它们已经介绍了其他材料例如其他材料其他材料例如 材料或 LAT 材料您应该停用 RAR还有 这些材料这是一个很容易用的材料如果您想做一些改造这些材料很容易用我可以把材料的材料放在空间或 LAT 上也许是用的材料我还能看到这是新的 新的 新的 新的材料但我认为我可以直接使用Rack-Hangle 材料去刷新的材料为什么呢我使用了我认为 这些材料为什么可以直接使用一个简单的材料这样的材料这是我们可以很快的做的刷新的材料好那么让我们开始看来现在的材料尝试材料的材料也许您可以看到现在的材料他有些材料一个材料它有些材料它有些材料那个材料它有些材料而且它有些材料一个材料每个材料有些材料它有些材料适当的材料但是我认为,如果我把所有的领域移到一个分层的团体里我可能想建立一个团体叫做 《玩家》这些领域应该成为一个领域的一个领域的一个领域所以这些领域是不可能的我可以介绍一些设备的设备比如《玩家》而且也有数个计划每个计划的每个问题然后有一个计划是谁是目前的比方还有一个计划是否目前的比方是否得到的奖励箱是否大多数给大家返回好,好但我从这点起我发现了一个问题因为我已经有计划我已经有计划在计划中特别的利用人物在计划中每个计划在计划中每个选择但是在计划中我仍然有一个价值在计划中价值价值所以这是一种迷茫或者迷茫这种这种在计划中我发现这种可能是计划中每个计划每个选择但是在计划中我仍然有一个价值所以这是一种迷茫的计划所以这是一种可能的改变我们需要计划还是没有但是我也都那个但是我们需要计划中这种肆意但是我们需要SYM我们需要SYM需要SYM poi kilometres最先我想今天做一个大家我说这是明從就像如果用户没有六个锅子这个功能会变成两个锅子这就代表用户赢了所以在订阅这个稿子里是非常烦恶的因为刚才在订阅锅里就像是一个户赢了当他有六个锅子但这个功能如果我订阅基本上告诉我一个户赢只要他没有六个锅子这就是我的看法我的观察在订阅锅子里所以当我们订阅有什么错有这个功能不过订阅是错的或者订阅的名字是错的所以要改变我们来订阅然后我们有一个功能它基本上选择用户赢每个户赢根据每个户赢每个户赢每个户赢每个户赢每个户赢每个户赢每个户赢每个户赢能供给控制 Courgér他就是 극争国联国家国内中国66 없는国内然后再次重新重新你也看到了一些雙方式在這裡被打敗的雙方式至少三次還有很多雙方式你可以嘗試把雙方式雙方式的雙方式通常這種雙方式也叫做魔法雙方式或魔法雙方式所以這些雙方式你應該要把雙方式用雙方式的雙方式每個雙方式都需要有名字這些雙方式我會示範一下然後你會有一個功能用來建立一個新的雙方式然後你會這個雙方式只是一些碳它們基本上都需要用來解釋你會有50個每個雙方式但是你會發現那些雙方式雙方式那些雙方式都需要有名字不過這雙方式會有一個新的雙方式我會稱為雙方式你會有三個雙方式你會有四個雙方式這是雙方式需要解釋你會有每個雙方式或者忘記然後將雙方式返回所以你會保持就是怎樣的功能我现在就在这里如果你做一个注意的语言其实你能够发现这个功能没有使用在任何地方所以我可以做一个快速搜查所以这些功能在哪个地方都可以使用这一部分也试试这就是我唯一的功能我所谓的功能叫做是可以使用所以它基本上没有使用如果功能没有使用通常你只能把功能删除好,让我们开始我们有一个功能在这里这些功能叫做在这些功能中它是一种功能使用新的游戏基本上你把游戏名字伸出去然后每个游戏你必须认识一些地方你必须认识这个游戏你必须认识一些金刚用这个游戏也认识他或她在对方的手机里认识的所以整个游戏似乎只是认识游戏所以我现在要说可能会把游戏调整合成一个各式的游戏然后整个游戏认识的游戏是在背景键里的键盘里放进制作者的键盘里这就是研究器的可能性我会改变这些我还有一些键盘键的键盘在这里你能看到这是有明显的因为我利用ES Lynch 键盘这些键盘自行取代有一些怪怪的行为因此这些键盘的键盘因为通常讯息的建议用途觉得 waste of invoices就可以让两个接触过于你进行讯息之后应该把这些讯息投给其他公司带给免费宝贝那还要等待在调书的凭掌这些讯息只要等待他们将还起来这样的话大部分的讯息互动的容讯是一个很实用的东西我需要销售到公司所以也许我可能需要監视所有的销售销售到一个很简单的功能因为现在我们看到销售到公司如果需要改变明天我们看到销售到一个标准需要销售到一个标准如果我现在的设计我需要改变所有的销售我需要改变所有的销售销售到一个标准需要改变所有的销售所以如果我能有一个重要的功能可以选择销售然后如果我真的想改变销售的销售我需要改变那一个销售有更多的研究所以我可以改变所有的销售销售到一个标准所以我可以改变工程之后还有一个功能叫做How Many Players如果您查看它是否使用的您可以看到它只使用在这个销售只使用在这个这个销售的功能如果它只使用在这个功能如果它只使用在这个功能然后我肯定不需要使用这个功能使用这个销售的功能OK,让我选择这个因为这个是非常有趣的ES5这个销售基本上是使用古代的销售那些销售的销售从ES6开始你肯定不会使用销售所以其他的功能我肯定会选择这个销售的销售但是它是一个非常有趣的销售我们肯定会选择是的然后有一个功能叫人接下来的问题我发现可能问题是这一个功能就是把第一个销售的销售然后我记得每个销售的销售每个销售的销售每个销售你只能把第一个销售的销售把第一个销售的销售那些人把同一个销售的销售把同一个销售的销售然后如果有一个销售是否能够完成销售的势力好的于这个销售的销售我们就注册我们就发现抓紫然后销售的销售我们就注册有数个销售的销售可以看到你帮笔上的销售你帮笔上的销售你帮笔上的销售然后你可以看到这里有点複计这几个轮子在这里我介绍的是这几个轮子所以轮子基本上就是複计这些複计在这里所以这些是我们能够改变的东西将它们移动到我们的複计然后再移动它们的複计在两个位置去取消複计所以我们有另外一个功能它们要查到 whether the user answered the question correctly or not其实在订阅我们的複计中我感觉它们的名字可能是错误的它们的功能不一定是回到複计的价值它们是回到複计的价值但是在订阅我们的複计中如果 user answered the question correctly那么在订阅我们的複计中要否移动 user to the new position or not这些複计不一定是正式的因为它们的名字是正式的所以这是我们能够订阅它然后再做一些改变在终于有另外一个功能它们要查到如果 user answered the question wrongly所以这是一个很简单的订阅现在你可能会发现这是一个很简单的订阅这些订阅中的订阅我非常惊讶原来的订阅者他可以写这些询阅但其实他是一个很好的订阅他写了这些询阅他用这些询阅来写一些询阅所以你能继续做迫性订阅这些订阅者他可以写这么多询阅在这么小的订阅中希望很多询阅的询阅在你的订阅中不太好好现在我们看看询阅中的询阅我们写了询阅我们有很好的订阅我们也有很多询阅的询阅接下来我们要做一些迫性订阅但之前我们做迫性订阅我们需要一些询阅所以在询阅中的询阅如果你得到询阅的询阅没有迫性订阅你必须做迫性订阅你必须做迫性订阅你必须做迫性订阅你必须做迫性订阅你必须做迫性订阅所以我可以给你一些例子在这段时间今天你可以用询阅的询阅我写的询阅但我努力去回顾去解释询阅的询阅如何所以我写了询阅的询阅我写了询阅的询阅这就是询阅的询阅询阅的询阅对不起我需要先介绍你如何在询阅的询阅记得询阅的询阅的询阅第一步是迫性订阅的询阅从订阅的询阅第二步是需要写一些询阅去写询阅的询阅询阅的询阅ya然后 写下询阅的询阅在新订阅的新篇然后 写下询阅的询阅用笔订阅的询阅这是应该写下询阅的询阅我的询阅这次我写的询阅在这里写下询阅的询阅将直接进入询阅然后 就将进入询阅的询阅然后 写下询阅的询阅如果每个人有可能的认识就会有一个认识的数据我用这些数据 as the golden master record所以我可以写出我的试试这里有些特别的东西要注意的是可能在开始这里有一个游戏游戏游戏游戏我认为游戏游戏需要使用个论变H arb论变H arb終よteok也要占糖O2O2Db15 going因为当年游戏者的行程中他们要移动这些软达的数字来调整一下帧数记住帧数当你移动帧数它的数字是软达的所以他们要移动帧数来调整一下帧数的数字它也要移动这个软达的数字来解决如果用了帧数就会对或不对所以这些是一种移动如果用了帧数就不可能回答问题这些游戏者来调整不同的图案 whether the user gets the answer correct or not这些图案是调整的by just calling this random function而根据结果there are some mysterious logic written here去判断 whether the userget the question right or wrong所以这些图案都要调整so this actually brings some challengeto the people who try to writethe golden master testbecause of this random functionyour program actually have some kind of a randomnesslet's see if you give a same input to this programbecause of this randomnessthe output or the behavior of the systemis actually different because it is randomizedso then one trick we used in this caseis I actually introduced a random parameterin this run game functionand this random functionactually can be supplied by me in my test caseand I will make some fake behavior therebasically I'm going to control this random behaviorI'm not going to let this programwhen I run my test casesI will supply a mocka fake implementation of this random number generatorso that I can control the random behaviorand so that I can controlone hour give a input to this programthe behavior of the system is fixedis not randomso this is a very tricky partand so later if you are going to implementthis random testI mean sorry this golden master testin another languageyou need to figure out how to do thisin your corresponding languagehow to fake a random number generatorinstead of using the original one used in your codeso let's go back to the one that I'm usingso this is the function I usein order to generate to theso-called golden master recordI firstly I need to write a fake implementationof that random functionso that given a particular numberit's called seedusually for a random number generatorthe first number in this number seriesis called a seed s-e-e-dand based on this seedand based on your random number generation functionit can determine all the subsequent numbersso basically that meansif you fix the seedif you fix this number generation functionthen you can control the whole sequenceof the numbers generatedin thisusing this number generatorand then that basically meansyou can control all the scenarioswhether you get the question right or wrongwhether he is getting out of the penalty boxall those things actually controlled by youin your test caseif you control the seed generationsorry the seed numberand as well as therandom number generation functionso in this caseI implementedmy ownrandom number generation functionand thenwhat I do is basicallysorry this one is just a helper functionso this is my placewhere I implementedthe sum of the helper functionbut the real oneis actually in this game runnersorry not game runnerprobably let me see where do I do itI should call it in thissorry okso this is the place I am usingso I wrote a functionwhich is to record the current system behaviorso you can see thatit takes into argumentsthe first argument is the seedand the second argument is the file nameso basically itfirstly deleteif this file is already thereif there just then delete this fileand thenredirect the consoleconsole log to that fileso rememberjust now I mentioned thatI would like to captureall the logs from the systeminto this fileso I need toI wrote a function herebasically to redirect the logI just overwritethe console.log variablethis is the kind of black magicyou can do in JavaScriptyou canbecause it is a global variableyou just reassign this global variableto another functionthen your systemwill start towhenever they call console.logactuallywill log it towhatever you supply herein this caseI supply a file nameconsole.logwill actually just log to that fileand you can easily do thisin other languages as wellso most of the languagesthere are some kind ofsimilar trickswhich allows youto overwriteredirect the logsto a new placeandthen let's go backto this functionso Ionce Iredirect the logsto thatlog fileand then I justneeds tooverwrite the seedSEEDin thisagain thismask.seedverbaland thenI just run this gameby supplyingmy fakeimplementationof the random number generatorso remember nowso basicallyusing the realrandom number generatorthe number seriesis actuallyunpredictableif the seed is 1the next numbercould be 2could be 4could be 68or 0.5so using a realnumber generatorI can'treally controlthe behaviorof theof the systembut using myfakednumber generatorI basicallyI controlthe starting pointwhich is the seedsorryso I'm controllingthe starting pointwhich is the seedand I'm also controllingtherandom number generatorfunctionthenbasically that meansI can controlthe second numberwhich couldaccording to myfunctionthis is the second numbermight be 100and thenthe third numberwould be 400all these thingsare kind of fixedor determinedbecause I supplymy ownrandom numbergeneration functionand that meansfor every scenarioI'm going to controlas long asI changethe seed numberI supplyto different seed numberand each seed numberin combinationwith myfakedrandom number generationit will controlthe whole sequenceof numbersand this wholesequence of numbersbasicallyis one particularscenariothe systemrealize onsuch as determinewhether the userget the questionright or wrongwhether the useris getting out ofthe systemiscontrolled bythose numbersand sinceI'm controllingthose numbersI'm actually controllingthe inputof this systemand thenI can possiblyrepeatthose scenarioslaterand to comparewhether mysystem behavioris the same asthe onethat I recordedin the in the in thegolden master recordso this partis a bittrickyso it willif Irelyingon thecodebaseI shareyou do notneed todigest this a lotnowprobably go homeandread about itbecauseduring therefactoringyou do notneed tomortifythis pieceof a codesobasicallyonthis pieceof a codewhat Idid isokayGolden Master RecordsIn my directoryIn my project codebaseI probably share you on theKithubYou can see thatI do have a directoryCalledGolden MasterIn thisGolden Master directoryI have a logic calledGolden Master Generatorwhich basically calls theand that function help me to generateright now I have ten log fileseach log file corresponding toone possible scenariothat I can control using my test caseand thateach log file is basicallysimilar to what you saw just nowwhen you run the code on the consoleand so I have nowI have this ten so calledGolden Master records under each scenarioand then I will write a test casebasically to call my systemusing those ten possiblescenariosand for each scenarioI get the latest outputI will compare with the correspondingGolden Master record in this filein this folderand if they look the samethat means my behaviorof the system behavioris the same as what I recordedbut if Imake some changes in the codeand that make the behavior changeagain by right the test casewould flag out oh something is changedthen the test case would failso this is howI wrote my test casecalledGolden Master testand this onebasically just callthe systemusing those seedand the seed numberwe are ranging from zero to noneand for each scenarioit will generate the newrecord againandfirstly if you load the master recordand then it will record the current behaviorand thenI have aexpect function herebasically I'm expecting mynew recordshould match with my master recordthis is basicallyso this is basically theGolden Master testjust to check whether your system behavioris the same asyour current behavior is the same aswhat you recordedso I can show you how this is workingso currentlyI'm already runningI'm already runningthis test case heremaybe it's better for me to show you in the terminalso I can justrun my yarnI'm using yarnas a toolfor running my test casesso you can see that it willautomaticallyrun my golden master testright now everything passbut if I just introduce some change in my codefor exampleso if Iintroduce some change in my codelike in this game.jslet's see if I'm going to changelet's see if I modifythis number 8if I change this tonumber 3then I'm introducing a change in my codeand nowif I'm going to run my test caseagain I'm expecting mygolden master recordgolden master testto capture this changelet's seeso it works nowso you can see that because I changedthe behavior of the systemthe outputis differentso given the same inputis differentthen based on this I know thatsomething is changedin the code that affect the behaviorof the systemand I should do this latercontinuouslywhenever I do refactorso basically while I'm running thewhile I'm going to do the refactoring of the codebaseI'm going to keep running this golden master testin the backgroundand each time if I modify somethingand then I will quickly checkis the test case still passed or notif the test case passedthat means the system behavior is not changedthat means my refactoringis goodif I introduce something that breaks the systemthen the test case will tell me right awayso this is howit worksat this point are there any questionsregardingthis golden master testso forwe will take more time laterat home you can read about howthis master records are generatedfor now we will just keep it runningin thebackendI will just keep this running in mybackendand whileI'm going to do some refactoringon the codebaselet me get some moreyesmy master recordtext foldertext fileshow do you get a 10 text filethose 10 test files are generatedusing my file calledgolden master generatorsoso there is athis file called master generatorthis is the one that is calling the functionI showed you just nowbasically there is a follow up hereusing the seednumber from 0 to 9and for each seedit basically called this functionget master recordfirstly it will generate the file namewhich contains this seed numberso that I can get a unique file namefor each scenarioand then it causesrecord current behaviorwhich takes the seed and takes the file nameand this one will basically run the programusing this random numberand then output will be loggedto this file namethis is how I generatedthe 10how I generated the 10 records hereso for that loop imagine thatif you just change thisthisif you just change this value herefrom 10 to 100or 1000then you can easily generate100 golden master recordor 1000 golden master recordsoyou will be comparing the code fileswith the new imagechange the variable factor of codeyou will compare what we have nowwith the text filesyesso this is the logic in thejust now I show you is in thegolden master testso this golden master test will bekeep runningI will keep running this one in the backgroundyou thought in the backgroundyou will continuously keepcontinuously running this test caseto check if I modify the codethen it will run all the10 scenariosand for each scenario it willcompare the outputit did the same as the recorded copyand to determine whether the system behavioris the same as recordedyou probably need to runyarn install firstand then run yarn testthat the test case should beall passing right nowmaybe let itpause for a whilemy code maybe lets pause for a whileand make sure everyone canget the test cases runningyou can use our yarn test watchor test watchyessoif you look atthe npmthe package.jsonyou can see that I wrotea task there calledtest watchif you do thisyarn test watchit should start runningthe test cases in the backgroundand keep running itwhenever you make changes to your codelet's pause for a whileand make sure everyone can getthe test cases runningoh sorryfor those you are not usingjavascriptactually there isactuallyI do have a few othersamplesfor those who are using other languagesI do have a few links herethat basically shows you how togo the master testin other languagesin case you are usingone of those languagesyou probably can get some of thesample as wellI have a few using javatwo using javaone using csharpone python one javascriptnpmanyone using java hereyou use javawhat do you useok so I do have a csharp solutionhere as wellso there is one csharp solutionand one java solutionso I will pasteI will paste thisin thein the churchPythonthe python one is actuallyyour youtube videoI do not have the codei can share the slidesyou can probably check out the videoit is not a repository right nowso I will just pastethis two links thereso this isthis is javaand thenlet us also get the one forit seems thatit seems the first time when you run itit tends to failit should run generatedshould run generatedbut you think yourif you check out my codebasegolden master records are already thereso you do not need to generate new onesyou should just runis itokis this the errorok just runjust run it againjust typemy code have youpast the recordingit is very positivethis one but I do not really understandok soso the seed part is calledmaybe give me 5 or 10 minutesI just give you some examplesand then I will give you timeyou can then do your own refactoringoknot this oneso you really want to do refactoringas I mentioned that we need to keepthe test case runningso that we can constantly checkdid we make any changes that break the test casesso in this caseeither you can run itin a separate terminalor sometimes I preferjust to run everything in my IDEso I am using the visual studio codewhich hasthe integrated testsorry integrated terminalso I could just start my terminalis it already runningI just need to run theYarntest watchNPM run test watchnow it is already runningI will then probably make somerefactoring to the codefor examplejust now I mentioned thatsome of the variablesdeclared as varI know that they should be replacedwith const or letso I will do the replacementso using the IDEthen the shortcuthow to do the replacein the most efficient mannerso for me I am a vim userso I actually installed a vim pluginfor my IDEand if I want to do the replacementI will just run thewith something is wrongit doesn'tsorry just a moment something is wrongwith my IDEoknow it ishandlingsorry for the technicalissue my IDE ishandlingI probably need to restartmy vscodeI just upgraded the vscodeto the latest version last nightand it seems that the latest buildthere are some issueswith the plugins I usesomehow my IDEjust keep handingno respondingno it is not moving at allokinterestingit was working this morningI just was using itmaybe I shouldn't have upgraded to the latest versionokmaybe anyway let me do theprobably just do the simple thingsfirst are usinglet me probably start with vimok I will run itinok soso where is itshould be in game.jssure okI just want to run thisok this is runninglet me also go to theok so I just want toshow you the typical refactoring workflowso as I mentionedmaybe you just get your test caserunning in the background so it keeps runningand thenjust do ourcheck of your git statusmake sure that you have the latest codecheck out from code repositoryand then you can start doing somesimple changes in your codebaseso I generally would encourage youto start from simplersimpler activities you can dosuch as renaming a variableto make it moreeasier to understandor some simple improvementslike changing all this arrayimplementation into simpler formator extracting thedeplicate the code into common functionsand all those things are very easy to doand you can get yourget more familiar with the workflowfirst and then once your codeinto a better shapethen you can possibly consider todo some changes such asextracting some of the logicinto our player classand where is a common placeholderis a placeholder for the logicstate that are specificto the players etcso those things will introducesome structural change to a programso typically you can leave thattowards the later part of the refactoringto startaways just deal with thesimple stuffso in this case for exampleit's just not necessaryi can just use this bracketinstead of a new arrayand soall this i will just replacethis new arrayand i thinkthis should workbut how do i know that they are workingi should just checkmy test caseso usually whenever youmake some changes to a codethose test cases will automatically runlike for example if i introducea syntax error herethen this one shouldautomatically runcome onso this one should automatically runand then show meall the errorssomehowwhyit doesn't see any errorsorry i didn't save itstupidso if i save itthen you can see that the test case will automatically runand if anything goes wrongit will capture the error for youso in this caseso in this casei just simplified thisthis few arrays i simplified them usingthe just array literaland then my test case will automatically runand you can see everything is green nowso i just finished a verysmall changein this caseactually i recommend youjust do a commit local commit right awayso for everythis baby stepsas long as you finish the changeas long as the test case passthen you can make a committhen move on to the next changeso this if you follow this habitthat basically means that whenever you do a refactoryou probably make some wrong changeshalfway and you know that your codebase is probably screwed upso basically just revert back to the lastgood commit that you knowand then continue from thereif you do not do thisyou might accumulate several changesand then there is no easy way for you to revertback to a state that is good enoughso in this case i will just docommitandlet's seelet's see refactoringsimplifiedsimplifiedimplementation of arraysand thenthat's one one step, so I am doneand then i probably noticethat there are some of the varsas i mentioned just nowI would like to replace themat the best const or letdepending on whether they are constant orverbalso in this casei know that for example playersand places使用不同的记忆和设备所以我现在应该把这些设备改变成康兽所以我会把这些设备改变成康兽其实我可能会做一个改变用一些Vim的设备或者IEDE的设备我可以做一个全球的改变这次我会尽量改变很多VIRUS的设备进入康兽用Vim的设备这就是Vim的设备让你做一些设备和改变但你也可以用任何设备在IEDE的设备所以我现在要改变VIRUS的康兽所以我首先要改变康兽第二康兽 第三康兽这一康兽也要改变康兽这些设备我只会用Yes to改变它但这些设备的设备我设备的设备是一个细节我不想改变它所以它应该是细节然后这一康兽是一个细节我会改变它这个设备的设备是一个细节它应该是一个细节这个设备是一个细节这是一个细节这是一个细节这是一个细节我觉得这些设备也应该是一个细节所以我完成改变一些设备的设备是细节然后接下来我会改变其他设备的设备是细节所以我会改变VIRUS的设备是细节然后再改变这个设备是细节这个设备是细节好所以不过在这个设备的设备没有更多的设备我会改变它设备的设备是细节我怎么知道如果我的设备好了我只要 check the test现在我的设备还在所以也许我设备的设备是细节然后我会走细节对不起我还没有过存我用了我的设备我已经继续补过设备的设备I already lost the habit of saving files manually.So now you can see that I saved the filesand on this test case still pass.And then I will be ready to just do a commit again.So in this case, I will just do the commitfor this particular change.So this is OK.So this is to what did I do?So this is to replace var with let and const.So then I'm back to step one.So I can make further changes in my code.So every time just repeat this.Make some simple change.And then check whether your test case still pass or not.And if yes, then do a local commit and then repeat.So each time then you are just making a small change in your code base.And if you continue to do this after one hour,perhaps 30 minutes, you will notice that your code base getting cleaner, cleaner, bit by bit.And after one or two hours, your code base will look very different from the current oneand looks much more cleaner.Yeah, do you have any questions?Is it OK to change the var array of six elements by cost, which you have not mentioned?OK.Yeah, so the question is just now I made a change.I replaced some of the arrays of six into that empty array.So the question is, is this change safe or not?Did it break the system behavior?So I made this change because I was reading code early on.I know that in this number six here, it's probably not necessary.Because in some other language like Java,array is fixed size.So if you declare array of sixand later you want to change the size,you probably need to declare another array, et cetera.But in JavaScript, array is very similar to the listin other language.It's dynamic.So in this case, six is here is rather just initial size.It doesn't matter.So each time later, I know that I can start with empty list or empty array.And each time I'm adding a new player, it will just append to this array.So basically based on that,this initial size six really doesn't matter.So that's my guess.But how do I know that this guess is correct or not?So I make the change and then I run the test case.So if all the test case pass,that basically means I didn't really change the behavior of the test case,sorry, the behavior of the system,then that basically means my guess is correct.So the underlying assumption here is thatyour test cases will be able to catchlike all these edge cases or corner cases.Because there might be some corner scenario wherefor example like this initialthe future of six is necessary.Yeah.So you're right.So basically I'm brave enough to do the changes nowbecause I'm protected by all those golden master tests.And actually the more golden master testsI generate,the more confident I am.So I could possibly generate 100 recordsor 1000 records.And with that amount of golden master records,I'm pretty sure that if I introduce any little changein the behavior,that would be caught by all those test cases.So just like the one I can,I'm guessing that removing the six doesn't matter.And if I'm wrong,then the test case would detect that.This is basically the value of creatingthose so-called golden master tests.Then now you can basicallystart changing the code any way you wishand doing some kind of operationor surgery on the code base.And then if you ever break the code,then you will be notified without any error.Then you can safely check in your changesto the code,to the repository.Okay.So then with this,I think less probably you guys can go aheadby yourself to do the refactoring exercise.If you're not sure what is refactoringor if you need some help with your hand,we can just probably help youto get started with some simplerrefactoring test,refactoring cases.Okay.Michael,I think we can pause for now.Okay.Time to get your hands dirty.