Ruby Patterns
description
Transcript of Ruby Patterns
-
1. Introduction2. Adapter3. Builder4. Command5. Composite6. Decorator7. Factory8. Iterator9. Observer
10. Proxy11. Singleton12. State13. Strategy14. Template
TableofContents
RubyPatterns
2
-
ExamplesofPatternsinRuby
1. Adapter2. Builder3. Command4. Composite5. Decorator6. Factory7. Iterator8. Observer9. Proxy
10. Singleton11. State12. Strategy13. Template
RubyPatterns
TableofContents
RubyPatterns
3Introduction
-
Converttheinterfaceofaclassintoanotherinterfaceclientsexpect.Adapterletsclassesworktogetherthatcouldn'totherwisebecauseofincompatibleinterfaces.
classQuestattr_accessor:difficulty,:hero
definitialize(difficulty)@difficulty=difficulty@hero=nilend
[email protected]+=calculate_experienceend
defcalculate_experience@difficulty*50/@hero.levelendend
classHeroattr_accessor:level,:exp,:quests
definitialize@level=1@exp=0@quests=[]end
deftake_quest(quest)@quests
-
attr_accessor:hero
definitialize(old_quest,difficulty)@old_quest=old_quest@old_quest.difficulty=difficulty@hero=nilend
[email protected]+=@old_quest.doneendend
#Usagehero=Hero.newquest=Quest.new5hero.take_questquesthero.finish_questquestputshero.exp#=>250some_old_quest=OldQuest.newold_quest_adapted=QuestAdapter.new(some_old_quest,5)hero.take_questold_quest_adaptedhero.finish_questold_quest_adaptedputshero.exp#=>300
RubyPatterns
5Adapter
-
Separatetheconstructionofacomplexobjectfromitsrepresentationsothatthesameconstructionprocesscancreatedifferentrepresentations.
classBoardBuilderdefinitialize(width,height)@[email protected][email protected][email protected]=[]@board.monsters=[]end
defadd_tiles(n)n.times{@board.tiles2builder.add_tiles(3)builder.add_monsters(2)putsboard.tiles.size#=>3putsboard.monsters.size#=>2
Builder
RubyPatterns
6Builder
-
Encapsulatearequestasanobject,therebylettingyouparameterizeclientswithdifferentrequests,queueorlogrequests,andsupportundoableoperations.
classTurndefinitialize@commands=[]enddefrun_command(command)command.execute@commands
-
#Usagehero=Hero.newget_money=GetMoneyCommand.newheroheal=HealCommand.newheroturn=Turn.newturn.run_command(heal)putshero.health#=>110turn.run_command(get_money)putshero.money#=>10turn.undo_commandputshero.money#=>0
RubyPatterns
8Command
-
Compositionoverinheritance.Composeobjectsintotreestructurestorepresentpart-wholehierarchies.
classCompositeQuestdefinitialize@tasks=[]end
def
-
RubyPatterns
10Composite
-
Attachadditionalresponsibilitiestoanobjectdynamically.Decoratorsprovideaflexiblealternativetosubclassingforextendingfunctionality.
classItemDecoratordefinitialize(item)@item=itemend#[email protected]
classMagicItemDecoratorItemMagic
Decorator
RubyPatterns
11Decorator
-
masterpiece_item=MasterpieceItemDecorator(item)putsmasterpiece_item.price#=>20putsmasterpiece_item.description#=>ItemMasterpiece
#allnextlinesputs"dosomething"item.usemagic_item.usemasterpiece_item.use
RubyPatterns
12Decorator
-
Defineaninterfaceforcreatinganobject,butletsubclassesdecidewhichclasstoinstantiate.
classPartyattr_reader:membersdefinitialize(factory)@members=[]@factory=factoryend
defadd_warriors(n)n.times{@members2
Factory
RubyPatterns
13Factory
-
Iteratorhelpsyoutoiteratethroughacomplexobjectusinganinteratormethod.
classParentattr_reader:first_name
definitialize(first_name,gender)@first_name=first_name@gender=genderendend
classChild6putshero.cursed?#=>true
RubyPatterns
16Observer
-
Provideasurrogateorplaceholderforanotherobjecttocontrolaccesstoit.
classHeroattr_accessor:keywords
definitialize@keywords=[]endend
classComputerProxy#Forwardableallowsobjectstorunmethodsonbehalf#ofit'smembers,inthiscasetheComputerobjectextendForwardable
#WedelegatetheComputerProxy'suseof#theComputerobject'saddmethoddef_delegators:real_object,:add
definitialize(hero)@hero=heroend
defexecutecheck_accessreal_object.executeend
[email protected]?(:computer)raise"Youhavenoaccess"endend
defreal_object@real_object||=Computer.newendend
classComputerdefinitialize@queue=[]end
defadd(command)@queue
-
hero=Hero.newproxy=ComputerProxy.new(hero)proxy.add("somecommand")proxy.execute#=>raiseerrorhero.keywordsexecutingcommands
RubyPatterns
18Proxy
-
Defineauniqueinstanceofanobject.
classHeroFactory@@instance=nil
defself.instance@@instance||=HeroFactory.send(:new)end
defcreate_warriorWarrior.newend
defcreate_mageMage.newend
private_class_method:newend
#Usagefactory=HeroFactory.instanceanother_factory=HeroFactory.instanceputsfactory==another_factory#=>trueHeroFactory.new#=>RaiseException
Singleton
RubyPatterns
19Singleton
-
Thispatterntriestosimplifycomplicatedcontrolflowschanginganobject'sbehaviordynamically.
classOperationattr_reader:statedefinitialize@state=OperationOpenState.newend
deftrigger(state)@[email protected](state)endend
classOperationOpenStatedefnext(state)valid?(state)?OperationPendingPaymentState.new:raiseIllegalStateJumpErrorend
defvalid?(state)state==:pending_paymentendend
classOperationPendingPaymentStatedefnext(state)OperationConfirmState.newifvalid?(state)end
defvalid?(state)state==:confirmendendclassIllegalStateJumpErrorOperationOpenStateoperation.trigger:pending_paymentputsoperation.state.class#=>OperationPendingPaymentStateoperation.trigger:confirmputsoperation.state.class#=>OperationConfirmState
operation=Operation.newoperation.trigger:confirm#=>raiseIllegalStateJumpError
State
RubyPatterns
20State
-
Defineafamilyofalgorithms,encapsulateeachone,andmaketheminterchangeable.
classHeroattr_reader:damage,:health,:skillsattr_accessor:printer
definitialize(printer)@damage=10@health=5@printer=printer@skills=[:stealth,:driving,:intimidation]end
defprint_statsifblock_given?yield(damage,health,skills)elseprinter.print(damage,health,skills)endendend
classBattleStatsdefprint(damage,health,skills)"Damage:#{damage}\nHealth:#{health}"endend
classSkillStatsdefprint(damage,health,skills)skills.inject(""){|result,skill|result+skill.to_s.capitalize+"\n"}endend
#UsageHero.new(BattleStats.new)Hero.print_stats#=>Damage:10#Health:5
Hero.new(SkillStats.new)Hero.print_stats#=>Stealth#Driving#Intimidation
Hero.new(any_printer)Hero.print_statsdo|damage,health,skills|"Looks:I'mprintingacustomizemessageaboutmyherowithdamage#{damage}andnumberofskills:end
Strategy
RubyPatterns
21Strategy
-
Definetheskeletonofanalgorithminanoperation,deferringsomestepstosubclasses.Templatemethodsletssubclassesredefinecertainstepsofanalgorithmwithoutchangingthealgorithm'sstructure.
classHeroattr_reader:damage,:abilities
definitialize@damage=damage_rating@abilities=occupation_abilitiesend
defgreetgreeting=["Hello"]greeting
-
defoccupation_abilities[:magic_spell]end
defunique_greeting_line"Mageisreadytomakepowerfulspells!"endend
RubyPatterns
23Template
IntroductionAdapterBuilderCommandCompositeDecoratorFactoryIteratorObserverProxySingletonStateStrategyTemplate