Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ruby OOP Lesson Plan #77

Open
KevinMulhern opened this issue Nov 25, 2021 · 9 comments
Open

Ruby OOP Lesson Plan #77

KevinMulhern opened this issue Nov 25, 2021 · 9 comments
Labels
ruby Status: Discussion This issue/PR has an ongoing discussion Type: Enhancement Involves a new feature or enhancement request

Comments

@KevinMulhern
Copy link
Member

Title Author Date
Ruby OOP Lesson Plan Kevin 25/11/2021

Ruby OOP Lesson Plan

Summary

Currently, we have one huge lesson in the Ruby course for teaching OOP. We could teach OOP better if it was spread among multiple smaller, but more in-depth topic lessons that include exercises.

We first need to decide on a lesson plan, this issue can serve as a place to collect ideas for the lessons until we have a concrete lesson plan ready.

Motivation

  • We can better teach concepts in dedicated lesson just for that concept where we can go in-depth and provide exercises to reinforce new knowledge.
  • It will be easier to expand the OOP section in the future as adding new lessons is a lot easier than adding to the existing big lesson.
  • It takes a long time to go through the current lesson, smaller lessons will be completed quicker, giving an increased sense of progress.

Suggested implementation

First of all we need to come up with a lesson plan.

Additional

@KevinMulhern
Copy link
Member Author

Lots of really good ideas here, specifically around design with objects and their relationships between each other: https://discord.com/channels/505093832157691914/540903304046182425/913208304484896808

@ChargrilledChook
Copy link
Member

Two issues with the current lesson are:

  1. It's a big info dump immediately followed by large-ish projects

  2. The code for these projects is non-trivial for learners at that this stage, and we're expecting them to use OOP on top of that, which is itself a large and confusing topic for beginners.

Breaking up OOP with more lessons and projects will help with improving 1. To solve the second issue, I think it would be a good idea (especially early on) to introduce some projects that are focused on objects and OO design without as much focus on general programming problems (such as TTT / connect 4 win methods, or Mastermind code breaking algos).

Breaking up the projects a bit more conceptually like this could help to remove a bit of the cognitive overhead when starting OOP - one of the most common points of feedback for TTT is that people have no idea where to start, or what objects to create.

Project Idea - A playing card game program

The broad idea for this project is that it's completed across several different lessons. Learners would do a lesson, be introduced to some concepts and then do a section of the project. In the next lesson, they would be introduced to a new concept, then revisit the same project but have to extend or modify it with some new requirements. The project would gradually grow in complexity and break up the process conceptually a lot more.

Example Layout

  1. After the intro / basics lesson: First section is basic and focused on object creation and relationships. Learners create a card object, a pack object, and a hand object. Perhaps some simple methods to create some random hands by drawing from the deck, and then printing them to the console

  2. After an inheritance lesson: Introduce requirements to create different kind of deck objects - for instance, a half deck instead of a standard 52 card pack. Add an UNO deck as well. Use this as a vehicle to teach inheritance.

  3. After a composition lesson: Introduce a requirement for a half UNO deck. Use this an example of the limitations of inheritance, and an opportunity to practice some basic composition instead (learners could refactor or simply solve this requirement with composition instead)

  4. More general ideas: slowly introduce more and more objects into the project, such as players, boards, games, chips etc. Learners could begin with implementing a simple card game (such as war) and go on to something more complicated such as patience, blackjack, poker, etc.

Ideally learners should be able to add new games to their project without having to refactor their previous classes - demonstrating how we can build up complex systems in OOP and substitute objects to get different results.

There's a lot more you could do with this concept and a lot of different ways to approach it, but I think it's a good topic to explore a variety of concepts in OOP. Allowing people to practice different concepts in a more incremental fashion will help ease people more gently into something that is often a difficult topic for beginners.

@linkonsat
Copy link
Contributor

OOP Section Lessons Ideas

Let me know if there is anything that needs further explanation!

Main issues

  1. Lots of info dumped at once making it hard to remember the overall important concepts surrounding OOP. Learners may also feel better about making progress on the section if lessons are broken into smaller pieces.
  2. It’s not clear after doing the OOP section in its current iteration what are some design principles or best practices that can be utilized to write clean code within an OOP style.
  3. A few issues I noticed when helping individuals is they will either put multiple classes in the same file or give their classes responsibilities that fall outside of the respective scope of their class, Issues can occur due to how they have designed interactions between files, etc.
    Solution

Solutions summary

  1. I believe these issues could be helped by breaking the OOP lesson section into smaller lessons that cover aspects of OOP programming more concisely such as composition, SOLID principles, Communication between classes, etc.
  2. Introduce a project that steadily builds upon the principles by adding different features that can utilize OOP principles as they learn.
  3. Introduce a few exercises at the end of each lesson end to reinforce the respective lessons. One of the issues that I see with, not including any exercises is that it could still feel like diving within the deep end. A few exercises to have a person thinking about how to apply those principles then go into creating a feature might help provide ideas for how to conceptually implement these ideas within the project they build throughout the OOP section.

General Lesson Layout

SOLID Lessons

  1. Start by breaking down a typical example of how we might construct a project that involves multiple object files with different responsibilities. As well as how we might decide the scope of an object. For example, we would expect a plant to know itself such as diseased, what plant it is, how much water it needs. I would not expect a plant's scope of knowledge to extend beyond those boundaries such as how to get water outside of its own roots. Would also be a good opportunity to bring up designing our object in mind with what conditions there are such as sunny, cloudy, etc. through a message from another object.

  2. Next Lesson/lessons would Go over SOLID principles and how we can apply these to an example file
    Exercise-: 1-2 exercises asking us how to either better implement a solid principle OR give an exercise that intentionally throws an error and ask them to apply a SOLID principle to solve. This would be for each SOLID principle.
    Garden Bed mini-project-. After that section they would start building up the project. This lesson would then have them create the garden bed class object. The steps would follow the SOLID principles.
    Single-Responsibility- First create a garden object which utilizes a Soil, Plant, Garden Spot object utilizing Single-Responsibility to have those objects encompass what they would do.
    Open-closed principle- Use open-closed principle to add weather conditions method that can get rid of a plant without editing any of the class itself,
    **Liskov Substitution principle-**use the Liskov substitution principle to include a way to create garden box square instances from the parent garden box or a helper module that provides utility features such as soil conditions without coupling the garden box to it.
    Interface segregation principle- use Interface segregation principle to display and check if the desired plant is in the box without utilizing other interfaces
    Dependency Inversion principle- Use the Dependency Inversion principle to have a plant return a random price and create a method that returns a random garden box square instance utilizing the method from step 3 and displays it without editing the random garden box square instance if possible

Composition vs inheritance

  1. Composition vs inheritance
    Go over the benefits and drawbacks of each. For a few exercises have them compose a simple object such as a tax calculator. Show an example of a tax calculator that inheritance and violates a SOLID principle to point out issues of single class inheritance vs using include to allow for two modules that don't violate SOLID principles
    Creating a sales calculator- Have the learner create a sales calculator for the garden. Have them store the various prices in another class object that when requested by the user can return a price with the calculator adding a generic tax.
    Utilizing composition- At this point they should be able to retrieve a price from that module. As a benefit of storing it in a separate class. They can also compose a method of whether or not that price exists. By using that same method that returns a price they should be able to compose an error message such as “Requested plant does not exist”. This would highlight the key benefit of a composed object allowing methods to be used in unexpected ways.

    Object communication and interfacing

    Object Communication- Deeper dive into having objects communicate with each other. Specifically bringing up issues such as dependencies, how more dependencies can result in more brittleness in a class, length of a chaining method call, and the risks associated with depending on chained statements such as a change in any object that is communicated with putting your original object at risk of breaking. This could be one lesson however it is very possible this topic might need more than just one lesson. These lessons would lean more on the debugging exercises, however, A challenge could be to review the garden object and ask them if they are chaining methods beyond one or two-step or if there is any way to reduce brittleness between their objects. Exercises could include 2 deeply coupled objects that have very obvious ways they could be less dependent on each other. The learner would then have to decouple these two objects.

    Advanced OOP lessons

    1. Advanced ruby - this would go into deeper topics such as polymorphism, encapsulation, and abstraction, interfaces beyond just having segregated interfaces and explaining what they are but, going over the benefits. As well as a re-framing of thinking of building classes around the idea of what message are they sending, what behavior do we want and what state do we expect the object to be in. At this point, exercises would also go over these concepts. Finally, we would join the sales tax operator by including a storefront object. Which would highlight object communication and ask us to design it with the previous lessons and design the storefront with an emphasis on how we want messages sent.

    Final project?

    1. The final project would put these key concepts together, however, I don’t believe this project should take a long time compared to say the ruby capstone project. It would rather ask the learner to utilize the sections such as using the SOLID principles to do y or use x principles from the advanced ruby section to do z with the garden project. It is however possible after doing the advanced OOP Lessons that the garden project would be fully fleshed out and a different project may not be needed to bring it together. Another perspective is if a learner understands these principles and can utilize them I think the capstone project would be sufficient in regards to utilizing these principles. As chess has many different objects that communicate with each other.

@crespire
Copy link

crespire commented Jan 21, 2022

Just a quick thought for consideration. I think near the end of the Ruby OOP course, it might be worthwhile to introduce the idea of raising some basic errors, and a basic try/rescue structure. I still haven't used a rescue but I have started to raise errors now in my Chess program.

It might be good to fit in around/after the Composition/Inheritance discussion, as then if something comes back not what you expect you have a tool to handle it. I see that the example provided by @linkonsat touches on handling an error for prices not existing, so perhaps it would fit right in that lesson as a quick aside.

@JoshDevHub
Copy link
Contributor

I don't have a specific project idea, but I do have a couple thoughts regarding expansion of the OOP lesson:

  1. I think the concept of an 'interface' must be introduced. This is one of the more common problems people have when they get to Tic-Tac-Toe: how do I get my objects to talk to each other? This is a big reason many Tic-Tac-Toe projects get written procedurally because if you don't know the basics of object communication, can you even write OO code? I think the lesson needs to be strong enough to where students can approach TTT utilizing OOP, and this is the main obstacle to that currently.
  2. I think more advanced concepts (polymorphism, duck-typing, abstractions, etc.) could be great to include at some point in the curriculum, but I'm skeptical of their value if placed directly before Tic-Tac-Toe. There's a reason we commonly tell people to put off POODR/99 Bottles until they've written some OO code. It's very difficult to understand the utility of these things without having gone through the problems caused by their absence. If lessons revolving around these concepts are introduced, I think it's a better idea to place them later in the curriculum -- perhaps around testing?

@thatblindgeye thatblindgeye added Status: Discussion This issue/PR has an ongoing discussion Type: Enhancement Involves a new feature or enhancement request labels Jan 27, 2022
@crespire
Copy link

crespire commented Feb 2, 2022

This is not necessarily strictly related to OOP, but I think it would be a benefit for this portion of the course to go over standard practice on how to structure projects in terms of your directory structure and maybe how to utilize bundler to build a project foundation.

I am still not sure the best way to "make" a Ruby project, aside from making a repository and adding folders, then initializing rpsec.

@RolandStuder
Copy link

Awesome work here! I like the card / deck of @ChargrilledChook a really approachable idea, as people are generally well familiar with the concept of cards, decks, and hands.
I love @linkonsat depth of applying the OOP / SOLID principles but found the garden bed example a bit less approachable.

I highly agree that with @JoshDevHub that we need to teach how objects talk to each other, that seems to be a big stumble stone for many, who then reach for global or class variables to access state. I think the lessons should focus on practical stuff like that even before going in too heavy into SOLID principles, that have weird names and that are kind of abstract.

Looking forward to some great content here!

@crespire
Copy link

crespire commented Oct 3, 2022

Are there any plans to embark on this revamp after the current, on-going projects are completed? I was thinking about this thread because of Hacktoberfest.

One note I wanted to add was that the discussion so far has been great, but quite centred on the "how" of OOP. Given the way the topic is currently introduced, the course dives right in to the Codeacademy OOP lessons, then drops learners into the Launchschool book "for more details" - these resources are great, but I think they're quite technical.

The idea about introducing an interface would be a great place to talk about the why of OOP. I think that, alongside introducing an interface and the idea of objects talking to each other, providing learners with a why might help them to stick with the content even though it is pretty dense.

I think this "why" section could be added to the current curriculum, and also be useful and expanded on to add the discussion on interfaces in the future. Happy to work on a draft section if that sounds like something worthwhile.

@KevinMulhern
Copy link
Member Author

Thanks for taking the time to write that up @crespire 💪

Are there any plans to embark on this revamp after the current, on-going projects are completed?

Yes, definitely! It's top of the list for me after clearing our current batch of projects.

Completely agree on answering the why question up front. I think all lessons and even sections should start with the "why" in mind. Teaching learners why this thing exists and the problems it solves before diving into the specific details lays a much better foundation and makes content more engaging.

I don't think it should focus solely on interfaces though. In this case, I think we'd want a high level "Why OOP" lesson at the start of the new section and then in each lesson, a bit about the why for the topic of that lesson in the introduction.

I'm not sure if it's worthwhile doing this until we're ready to start this project. I'd hate for anyone to do work on this right now that may need to be cut when it comes to working on this proper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ruby Status: Discussion This issue/PR has an ongoing discussion Type: Enhancement Involves a new feature or enhancement request
Projects
Development

No branches or pull requests

7 participants