24-01-2022
Meta Stuff
I managed to really waste some time today via messing up git in the most banal way possible - in my (now complex) remote add origin commands, I rushed to add the GitHub remote. In the rushed process, I mistook a filename as a variable. I set the remote and couldn't reset it despite attempting to delete the remote, set-url, etc.
In an attempt to give easier access to the other party, I copy and pasted a file directly into GitHub - I knew this was going to cause an issue. I didn't anticipate a small merge conflict frustrating me so...
My quick fix was to simply make a new directory, since we only had a README.md file. Simple.
Then I made a new directory, set the correct git remote with the correct SSH key, and attempteda pull.
Git wasn't having it - to make matters more frustrating, I'm certain I've fixed this exact issue before. But time wasn't on our side.
It took me more than an hour to realise, after the pull, fetch, and rebase - the files weren't showing because I was, lemon I am, looking in the wrong directory. Sigh.
After that it was fixed! Thanks to HOOM'N, we were going along swimmingly already, but once we both set to the task, our TDD, REPL-experimentation, and eventual programming began to fly.
Still I'm frustrated to have cost us both such time - though HOOM'N was very eloquent and kind about it all. Ah. It's not the first time a merge conflict has thrown me for a loop. I doubt this one would be the last.
I didn't make a dent in the bud forms either...
Today's Foci
Focus 1
- Get some Bud forms completed
- Have at least first bud form done
Topic
Code Review
Really you can start anywhere, but I would probably start in the README for an overwiew.
Look at the file structure
Quick Wins in CR
- file structure
- check class names
- if a class only has one method, its not a class!
- check SRP - is the method_name doing only what it requires
- does code meet the user stories
- DRY
- format - ruby specs - layouts
- readability (be aware of when to use one-line syntax)
Good Major: Flowchart Good minor: great use of symbols
Improve Major: user Story and Story tables Improve Minor: instance vs class variables
Object Oriented Design
Managing Code Complexity
- Codebases tend toward complexity
- How do we manage complexity in codebases as a team/organisation?
OOP helps
- Avoid repeitition
- Break code down into small, simple parts
- Ensure the relationships between the parts are simple
4 Pillars of OO
we'll go to very, distant lands...
- Encapsulation
- Each object keeps it's state private
- Other objects don't have direct access to this state
- They can only access other objects via public functions
- An object manages it's own state via methods - no classes touch it unless explicitly allowed
- By default, another object can't change another object's state
-
The cat's cattributes are changed only by methods defined on the cat class ( and thus specific to each cat-instance )
-
Abstraction
- for each object, only high-level methods should be exposed for their use
- it should hide internal implementations and details
- internal operations should only be revealed to other objects when explicitly required AND directly interfacing
- to make a coffee machine function, I don't need to understand and make use of every individual thing a coffee machine might do - I only need press a button (or two) - think SRP for those buttons
- I don't need to understand a coffee machine to use a coffee machine
- I only need to understand a high level abstraction of it - press button, add coffee - press button, add milk
- Inheritance - has a time and a place
- Some objects are very, similiar, and share a common logic, but they're not entirely the same
- maybe think of class Human, with an inheritance of Child and Adult?
- In this case, where both Adult and Human inherit from Human, Child and Adult would share the the fields and methods Human use
- Child and Adult would also implement their own classes unique to themselves
- Polymorphism
- Means "many shapes" in Greek
- A collection (set of data - an array?) containing a mix of classes
- Or a method on the parent class that we would like to use for the child class?
- We can use a class as though it were it's parent
- Usually would happen by defining a parent interface, which can be reused
- The interface outlines a bunch of common methods
- Each child class implements its own versions of these methods
- When a collection expects an instance of a parent, polymorphism allows the language to implement the correct method
- A polymorphic interface allows inherited classes to access the parent interface; where each child has a unique version of that interface/method
Dependency Injection and Mocking
Pair is Oyster card
SOLID principles with Ruby
Resource for SOLID Ruby @rubygarage
Resource for SOLID Ruby @honeybadger
-
Single Responsibility Principle
- A class should have a single responsibility
- Perhaps the Weather class should have been in the Friday module?
-
Open/Closed Principle
- modules, classes, and methods should be open for extension, but closed for modification
- design in a modular way
-
Liskov Substitution Principle
- Subclasses should add to a base class's behaviour, not replace it
- If you feel inheritance is necessary, don't replace the original method - call super, and modify the behaviour in a secondary method
-
Interface Segregation Principle
- Clients shouldn't depend on methods they don't use. Several client-specific interfaces are better than one generalized interface
- A coffee machine shouldn't have one user interface for both a Barista and a Customer - there must be two seperate interfaces
- CoffeeMachineUserInterface
- CoffeeMachineBaristaInterface
-
Dependency Inversion Principle
- High level methods shouldn't depend on low level modules. Both modules should depend on abstraction. Abstractions shouldn't depend on details, because details, depend on abstractions
Break one class into two classes while maintaining test coverage
test classes using mocking and
T, Always write tests before the code!!!
If a class is empty - don't commit it! does it even need to be there
Useful Tactics
Naming
- camelCase
- PascalCase
- snake_case
- kebab-case
Flow in Markdown?
only using mermaid, or jekyllSSG with mermaid, it seems. A journey for another day!
Methods Learned Today
the ruby send() method? look into this later (note: this is ruby only, not rails)
Gems Learned Today
Bundle init
gemfile act as reference
manifest & 3rd party dependency manager
must be in root directory
in rails, goes in same file as rakefile's gemfile is evaluated as rubycode
rubygems.org
bundler.io
gem has name, version, platform
platforms are based on cpu architecture
lib is the source code in ruby
specs testing framework
rakefile - Make like programme
standard ruby syntax
bin directory loaded into the users path when installed
documentation in README
finally, gemspec
% tree freewill
freewill/
├── bin/
│ └── freewill
├── lib/
│ └── freewill.rb
├── test/
│ └── test_freewill.rb
├── README
├── Rakefile
└── freewill.gemspec
- make a gemfile
- specify correct source for gems
- latest version
- gem install rspec