Menu
Coddy logo textTech

Kompozycja interfejsów

Część sekcji Programowanie obiektowe ścieżki GO w Coddy. Lekcja 31 z 107.

Go pozwala tworzyć większe interfejsy przez komponowanie mniejszych. Zamiast definiować jeden duży interfejs z wieloma metodami, osadzasz istniejące interfejsy w definicji nowego interfejsu.

type Reader interface {
    Read() string
}

type Writer interface {
    Write(data string)
}

// ReadWriter łączy oba interfejsy
type ReadWriter interface {
    Reader
    Writer
}

Interfejs ReadWriter wymaga teraz zarówno metod Read(), jak i Write(). Każdy typ, który implementuje obie metody, spełnia wymagania interfejsu ReadWriter, a także osobno interfejsów Reader i Writer.

type File struct {
    Name string
}

func (f File) Read() string       { return "file content" }
func (f File) Write(data string)  { fmt.Println("Writing:", data) }

func Process(rw ReadWriter) {
    content := rw.Read()
    rw.Write(content)
}

func main() {
    f := File{Name: "data.txt"}
    Process(f)  // File spełnia interfejs ReadWriter
}

To podejście oparte na kompozycji pozwala zachować małe i skoncentrowane interfejsy. Możesz łączyć je według potrzeb, tworząc precyzyjne kontrakty dla swoich funkcji. Biblioteka standardowa Go szeroko wykorzystuje ten wzorzec, na przykład io.ReadWriter, który łączy io.Reader i io.Writer.

challenge icon

Wyzwanie

Łatwy

Stwórzmy system odtwarzacza multimedialnego, który demonstruje kompozycję interfejsów. Utworzysz małe, wyspecjalizowane interfejsy, a następnie połączysz je w bardziej rozbudowany interfejs, który może spełniać jeden typ.

Rozmieścisz swój kod w dwóch plikach:

  • media.go: Zdefiniuj trzy interfejsy i strukturę, która implementuje je wszystkie:
    • Interfejs Player z metodą Play() string
    • Interfejs Recorder z metodą Record(content string) string
    • Interfejs MediaDevice, który łączy interfejsy Player i Recorder
    • Strukturę SmartDevice z polem Name, która implementuje wszystkie wymagane metody
  • main.go: Utwórz funkcje demonstrujące, jak można używać tej samej struktury SmartDevice za pośrednictwem różnych typów interfejsów. Napisz trzy funkcje:
    • UsePlayer, która przyjmuje Player i wywołuje jego metodę Play
    • UseRecorder, która przyjmuje Recorder oraz ciąg znaków z treścią, a następnie wywołuje Record
    • UseMediaDevice, która przyjmuje MediaDevice oraz ciąg znaków z treścią, a następnie wywołuje zarówno Record, jak i Play
    Odczytaj z wejścia nazwę urządzenia i treść, utwórz SmartDevice i pokaż, jak używać go za pośrednictwem wszystkich trzech typów interfejsów.

Podane zostaną następujące dane wejściowe:

  • Wiersz 1: Nazwa urządzenia
  • Wiersz 2: Treść do nagrania

Twoje metody powinny zwracać ciągi znaków w następujących formatach:

  • Play(): [Name] is playing
  • Record(content): [Name] recorded: [content]

Na przykład dla danych MyPhone i voice memo wynik powinien wyglądać następująco:

MyPhone is playing
MyPhone recorded: voice memo
MyPhone recorded: voice memo
MyPhone is playing

Pierwsze dwa wiersze pokazują użycie urządzenia za pośrednictwem pojedynczych interfejsów (Player i Recorder). Ostatnie dwa wiersze pokazują użycie go za pośrednictwem złożonego interfejsu MediaDevice, który wymaga obu możliwości. Zwróć uwagę, że Twoja pojedyncza struktura SmartDevice spełnia wymagania wszystkich trzech interfejsów, ponieważ ma obie wymagane metody.

Spróbuj swoich sił

package main

import (
	"bufio"
	"fmt"
	"os"
)

// TODO: Zaimplementuj UsePlayer, która przyjmuje Player i wywołuje jego metodę Play
// Powinna wypisać wynik Play()

// TODO: Zaimplementuj UseRecorder, która przyjmuje Recorder i ciąg znaków content
// Powinna wypisać wynik Record(content)

// TODO: Zaimplementuj UseMediaDevice, która przyjmuje MediaDevice i ciąg znaków content
// Powinna wypisać wynik Record(content), a następnie Play()

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	scanner.Scan()
	deviceName := scanner.Text()
	
	scanner.Scan()
	content := scanner.Text()
	
	// TODO: Utwórz SmartDevice o podanej nazwie
	
	// TODO: Użyj urządzenia przez interfejs Player
	
	// TODO: Użyj urządzenia przez interfejs Recorder
	
	// TODO: Użyj urządzenia przez interfejs MediaDevice
	
	_ = deviceName
	_ = content
	fmt.Println("Implement the solution")
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Go online