2017-08-21 3 views
0

Disons que nous avons la classe suivante (simplifiée):Le partage de codes lorsque la composition en utilisant

class AudioRecorder { 
    private func onRecord(data: [Float]) { 
     self.delegate?.audioRecorder(self, didRecordFrame: audioData) 

    public func record() { ... } 
    public func stop() { ... } 
} 

Il enregistre cadre et délégué informe de ce sujet. Maintenant je dois étendre les fonctionnalités suivantes:

  1. Buffering - Numéro tampon X de cadres
  2. d'enregistrement par intervalles - Enregistrement - Arrêt 1s - Record - arrêt 1s ...
  3. mise en mémoire tampon Intervalle - Enregistrement dans des intervalles et un tampon

Je ne peux pas utiliser l'héritage pour cela parce que si IntervalRecorder et BufferingRecorder sont sous-classes alors j'ai problème la mise en œuvre IntervalBufferingRecorder.

D'autre part, lors de l'utilisation solution de composition pourrait ressembler à ceci:

class BufferingRecorder { 
    private let recorder: AudioRecorder 

    func audioRecorder(recorder: AudioRecorder, didRecordFrame: [Float]) { 
     // buffering logic 
    } 

    // need to duplicate play and stop 
    func record() { 
    self.recorder.startRecording() 
    } 

    func stop() { 
    self.recorder.stop() 
    } 
} 

Je dois dupliquer les méthodes de pause de lecture dans toutes IntervalRecorder, BufferingRecorder et IntervalBufferingRecorder et juste avant d'objet sous-jacent.

Quelle serait une bonne approche de ce problème? La langue est rapide mais je suppose que ce n'est pas très important.

+0

Il y a une vidéo célèbre WWDC sur la programmation orientée de protocole et est un autre tutoriel ici https://www.raywenderlich.com/148448/introducing-protocol-oriented-programming. Passez par là et vous aurez l'idée. – adev

+0

Votre question est un peu vague pour moi, cela pourrait être mieux si vous pouvez essayer d'expliquer un peu plus sur vos classes et sous-classes. Si vous voulez éviter l'héritage, essayez d'utiliser un protocole avec une implémentation par défaut. – KeranMarinov

+0

'play' et' stop' ne sont pas des fonctions d'enregistrement, et cela viole le principe de la ségrégation de l'interface (non?). Je voudrais séparer le comportement 'Recorder' dans sa propre classe et utiliser le modèle' Decorator'. Un 'AudioWidget' aurait des méthodes' play' et 'stop' par défaut qui fonctionnent sur son instance' recorder' que vous pouvez configurer à volonté. – Fuhrmanator

Répondre

1

Cela peut vous donner une idée sur l'utilisation des protocoles avec l'implémentation par défaut.

protocol Bufferable { 
    func buffer(data: [Float]) 
} 

extension Bufferable { 
    func buffer(data: [Float]) { 
     print("buffering") 
    } 
} 

protocol Recordable { 
    func record(data: [Float]) 
} 

extension Recordable { 
    func record(data: [Float]) { 
     print("recording") 
    } 
} 

class AudioPlayer: Bufferable, Recordable { 

    func start() { 
     buffer(data: [2.0, 1.0, 1.0]) 
     record(data: [2.0, 1.0, 1.0]) 
    } 

} 

class VideoPlayer: Bufferable, Recordable { 

    func start() { 
     buffer(data: [2.0, 1.0, 1.0]) 
     record(data: [2.0, 1.0, 1.0]) 
    } 

} 
+0

Merci pour votre réponse, mais je pense que cela ne répond pas à ma question. Je ne veux pas polluer AudioRecorder avec autre chose que l'enregistrement. – josip04