@BryanWatts . , , . - . , , / .
, (LSP). LSP , interface .
, . , , . Speaker WirelessSpeaker , .
public class Speaker
{
public bool IsPlugged { get; set; }
public virtual void Beep()
{
if (!IsPlugged)
{
throw
new InvalidOperationException("Speaker is not plugged in!");
}
Console.WriteLine("Beep.");
}
}
public class WirelessSpeaker : Speaker
{
public bool TransmitterIsOn { get; set }
public override void Beep()
{
if (!TransmitterIsOn)
{
throw
new InvalidOperationException("Wireless Speaker transmitter is not on!");
}
Console.WriteLine("Beep.");
}
}
public class IBeepSpeakers
{
private readonly Speaker _speaker;
public IBeepSpeakers(Speaker speaker)
{
Contract.Requires(speaker != null);
Contract.Ensures(_speaker != null && _speaker == speaker);
_speaker = speaker;
_speaker.IsPlugged = true;
}
public void BeepTheSpeaker()
{
_speaker.Beep();
}
}
public static class MySpeakerConsoleApp
{
public static void Main(string[] args)
{
BeepWiredSpeaker();
try
{
BeepWirelessSpeaker_Version1();
}
catch (InvalidOperationException e)
{
Console.WriteLine($"ERROR: e.Message");
}
BeepWirelessSpeaker_Version2();
}
public static BeepWiredSpeaker()
{
Speaker s = new Speaker();
IBeepSpeakers wiredSpeakerBeeper = new IBeepSpeakers(s);
wiredSpeakerBeeper.BeepTheSpeaker();
}
public static BeepWirelessSpeaker_Version1()
{
Speaker s = new WirelessSpeaker();
IBeepSpeakers wirelessSpeakerBeeper = new IBeepSpeakers(s);
wirelessSpeakerBeeper.BeepTheSpeaker();
}
public static BeepWirelessSpeaker_Version2()
{
Speaker s = new WirelessSpeaker();
((WirelessSpeaker)s).TransmitterIsOn = true;
IBeepSpeakers wirelessSpeakerBeeper = new IBeepSpeaker(s);
wirelessSpeakerBeeper.BeepTheSpeaker();
}
(LSP). Agile Principles, Patterns and Practices # . 142-143
LSP , OOD IS-A , .... [W], , . , , , , . , . , [class].
TransmitterIsOn == true Beep WirelessSpeaker, , Speaker. WirelessSpeaker s IsPlugged TransmitterIsOn true, Beep , ( Speaker), a Speaker in TransmitterIsOn.
, SOLID, (ISP):
, .
a WirelessSpeaker . (, , .) WirelessSpeaker , IsPlugged, , Speaker, ! , , . , , , .
, LSP, ISP , , , Open/Closed Principle (OCP):
(, , ..) , .
, , Code Contracts . , ( ) , -, , .
, , : , . , , ; . , WirelessSpeaker?
, WirelessSpeaker Speaker. , WirelessSpeaker IsPlugged. , Speaker, , WirelessSpeaker , IsPlugged, true. " !" : " Beep, WirelessSpeaker ". , . ! WirelessSpeaker Beep, ! (, .) "", WirelessSpeaker; , , , .
, ? , , , . ?
- - .
- , , . , .
- (, ), - .
- , , . .
- .
, - . , :
public abstract class SpeakerBase
{
protected SpeakerBase() { }
public void Beep()
{
if (CanBeep())
{
Console.WriteLine("Beep.");
}
}
public abstract bool CanBeep();
}
! , . , CanBeep() true. , , , . , , SpeakerBase, , CanBeep() true. LSP! , a SpeakerBase , Speaker, WirelessSpeaker, : , .
, , - SpeakerBase:
public class Speaker : SpeakerBase
{
public bool IsPlugged { get; set; }
public override bool CanBeep() => IsPlugged;
}
public class WirelessSpeaker : SpeakerBase
{
public bool IsTransmiterOn { get; set; }
public override bool CanBeep() => IsTransmitterOn;
}
, Speaker, , . WirelessSpeaker, , . , WirelessSpeaker , "". .
, (DIP):
, Speaker WirelessSpeaker, SpeakerBase. , , , SpeakerBase, , , , . , IBeepSpeakers , , , , IBeepSpeakers . , IBeepSpeakers. ( , SpeakerBase Beep(), SpeakerBase , , . )
public class IBeepSpeakers
{
private readonly SpeakerBase _speaker;
private readonly Action<SpeakerBase> _enableBeeping;
public IBeepSpeakers(SpeakerBase speaker, Action<SpeakerBase> enableBeeping)
{
Contract.Requires(speaker != null);
Contract.Requires(enableBeeping != null);
Contract.Ensures(
_speaker != null &&
_speaker == speaker);
Contract.Ensures(
_enableBeeping != null &&
_enableBeeping == enableBeeping);
_speaker = speaker;
_enableBeeping = enableBeeping;
}
public void BeepTheSpeaker()
{
if (!_speaker.CanBeep())
{
_enableBeeping(_speaker);
}
_speaker.Beep();
}
}
public static class MySpeakerConsoleApp
{
public static void Main(string[] args)
{
BeepWiredSpeaker();
BeepWirelessSpeaker();
}
public static BeepWiredSpeaker()
{
Speaker s = new Speaker();
IBeepSpeakers wiredSpeakerBeeper =
new IBeepSpeakers(s, s => ((Speaker)s).IsPlugged = true);
wiredSpeakerBeeper.BeepTheSpeaker();
}
public static BeepWirelessSpeaker()
{
WirelessSpeaker w = new WirelessSpeaker();
IBeepSpeakers wirelessSpeakerBeeper =
new IBeepSpeakers(w, s => ((WiredSpeaker)s).IsTransmitterOn = true);
wirelessSpeakerBeeper.BeepTheSpeaker();
}
}
, , , . , , .