Introducing Complex Features While Maintaining Backward Compatibility in Go

Introduction

Welcome to today's lesson, where we will address a common challenge in software engineering: introducing complex features while preserving backward compatibility. Our focus will be on a Potluck Dinner organization system, where we will manage participants and their respective dishes for each round. Get ready for an exciting journey through Go programming, step-by-step analysis, and strategic thinking. Let's dive into our adventure!

Starter Task Review

Initially, our Potluck Dinner organization system allows us to add and remove participants and manage their respective dishes for each round. There are three essential functions:

  • AddParticipant(memberId string) bool: This function adds a participant. If a participant with the given memberId already exists, it won't create a new one but will return false. Otherwise, it will add the member and return true.
  • RemoveParticipant(memberId string) bool: This function removes a participant with the given memberId. If the participant exists, the system will remove them and return true. Otherwise, it will return false. When removing a participant, you need to remove their dish if they brought one.
  • AddDish(memberId string, dishName string) bool: This function enables each participant to add their dishes for every round. If a participant has already added a dish for this round OR if the memberId isn't valid, it will return false. Otherwise, it will add the dish for the respective participant's round and return true.

Let's write our Go code, which implements these functions as per our initial state:

package main

import "fmt"

type Potluck struct {
    participants map[string]bool
    dishes       map[string]string
}

func NewPotluck() *Potluck {
    return &Potluck{
        participants: make(map[string]bool),
        dishes:       make(map[string]string),
    }
}

func (p *Potluck) AddParticipant(memberId string) bool {
    if p.participants[memberId] {
        return false
    }
    p.participants[memberId] = true
    return true
}

func (p *Potluck) RemoveParticipant(memberId string) bool {
    if !p.participants[memberId] {
        return false
    }
    delete(p.participants, memberId)
    delete(p.dishes, memberId)
    return true
}

func (p *Potluck) AddDish(memberId, dishName string) bool {
    if _, exists := p.participants[memberId]; !exists || p.dishes[memberId] != "" {
        return false
    }
    p.dishes[memberId] = dishName
    return true
}

In this code, we used Go's map to store participant IDs and their respective dish names. With this foundation laid, let's introduce some advanced functionalities.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal