Definition
โข
์์ ์ ๋ถ๋ชจ์ ์์์ ๊ด๊ณ๊ฐ ๋ฐ๋์ IS-A ๊ด๊ณ๋ฅผ ์ ์งํ๋๋ก, ์ข๋ ์ ํํ ํ์๋ฉด, ๋ถ๋ชจ๋ฅผ ์นํ(substitution) ๊ฐ๋ฅํ ์์์ ๋ง๋ค๋๋ก.
โข
์์ ๊ด๊ณ ์ฝ๋ ์์ฑ ์์ ์์น. Base type์ ์ฌ์ฉ ์กฐ๊ฑด์ derived type์์ ๋ชจ๋ ๋ฐ๋ฅผ ์ ์๋๋ก
LSP violated sample
public class Line {
public Line(Point p1, Point p2){ /*code*/} }
public Point P1 { get { /*code*/} } }
public Point P2 { get { /*code*/} } }
public virtual bool IsOn(Point p) {/*code*/}
}
public class LineSegment : Line {
public LineSegment(Point p1, Point p2)
: base(p1, p2) {}
public double Length() { get {/*code*/} }
//Line.IsOn()์ ์ฐธ์ด ์๋์์๋ ๊ฑฐ์ง์ด ๋ ์ ์์.
public override bool IsOn(Point p) {/*code*/}
}
class LineClient {
void DoSomething(Line) { /*code*/ }
}
C#
๋ณต์ฌ
โข
LineClient.DoSomething()์ ํด๋น ๋งค๊ฐ๋ณ์(line) ์์ ๋ชจ๋ ์ ์์ IsOn() == true๋ฅผ ๊ธฐ๋ํ๊ณ ์ฝ๋ ์์ฑ ๊ฐ๋ฅ.
โฆ
ํ์ง๋ง ์ ๋ถ์ธ LineSegment instance๋ฅผ LineClient.DoSomething()์ ๋งค๊ฐ๋ณ์๋ก ๋๊ธธ ๊ฒฝ์ฐ, IsOn() == false๊ฐ ๊ฐ๋ฅํจ์ผ๋ก LineClient.DoSomething()์ ์ ํจํ์ง ์์ ์ฝ๋๊ฐ ๋จ.
โข
Base class client ์ฝ๋๋ ์ผ๋ฐ์ ์ผ๋ก derived class์ ๋ํ ์ง์์ ๊ณ ๋ คํ์ง ์๊ณ (base class์ ๋ํ ์ง์๋ง์ผ๋ก) client ์ฝ๋๋ฅผ ์์ฑ. ํ์ง๋ง ํด๋น client code๋ก derived class์ instance๊ฐ ์ ๋ฌ๋ ์ ์์ผ๋ฉฐ, ์ด ๋ LSP ์๋ฐ ์ ํด๋น operation์ ๋ฌดํจํ ๋จ. ์ฆ, ์ ์ฌ์ ๋ฒ๊ทธ ์ ๋ฐ ๊ฐ๋ฅ.
LSP ์ค์ ๋ฐฉ๋ฒ
1.
DBC(Design by Contract; ๊ณ์ฝ์ ์ํ ์ค๊ณ)
โข
Overriding ์, base class์์์ pre condition๊ณผ ๊ฐ๊ฑฐ๋ ๋ ์ฝํ ์์ค์์ ๋์ํ๊ณ , post condition์์๋ ๊ฐ๊ฑฐ๋ ๋ ๊ฐํ ์์ค์์ ๋์ํ๋๋ก ์ค๊ณํ์ฌ์ผ(Base class์ ๋ชจ๋ ๋ช
์์ /์์์ ๊ณ์ฝ์ ๋ง์กฑํ derived class ์์ฑ).
2.
deriving ๋์ factoring(๊ณตํต ์ธ์ ์ถ์ถ)
public abstract class LinearObject {
public LinearObject(Point p1, Point p2) { /*code*/} }
public Point P1 { get { /*code*/} } }
public Point P2 { get { /*code*/} } }
public abstract virtual bool IsOn(Point p);
}
public class Line : LinearObject {
public Line(Point p1, Point p2) : base(p1, p2) {}
public override bool IsOn(Point p) {/*code*/}
}
public class LineSegment : LinearObject {
public LineSegment(Point p1, Point p2) : base(p1, p2) {}
public double GetLength() {/*code*/}
public override bool IsOn(Point p) {/*code*/}
}
class LineClient {
void DoSomething(Line) { /*code*/ }
}
C#
๋ณต์ฌ
โข
Line๊ณผ LineSegment์ ๊ณตํต์ ํน์ฑ์ ์ถ์ถํ์ฌ ๊ณตํต ์์ ํด๋์ค(LinearObject) ์์ฑ
โฆ
LineClient.DoSomething()์ ๋ ์ด์ ์ ์ฌ์ ๋ฒ๊ทธ๋ฅผ ๊ฐ์ง ์์
์ผ๋ฐ์ ์ผ๋ก factoring์ ํตํ ๊ณตํต์ ์์ ํด๋์ค๋ abstract๊ฐ ๋ ๊ฐ๋ฅ์ฑ์ด ๋๊ณ , ํด๋น ์์ ํด๋์ค๋ ์ธ์ ๊ฐ ๊ทธ ์์ฒด๋ง์ client code๋ฅผ ๊ฐ๊ธฐ ๋ง๋ จ.
Conclusion
โข
LSP ์๋ฐ์ base class ๋ง ์๋ client code์ ๋ณ๊ฒฝ์ ์ ๋ฐํ๋ฏ๋ก(derived class์ ๋ํ ๊ณ ๋ ค๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์), OCP ์๋ฐ์ด๋ ๋ถ์ ์ ํ๊ธ ํ์์ ์ผ๊ธฐํจ.
โข
OCP ์ค์, ์ฆ ์ถ์ํ/๋คํ์ฑ ๊ธฐ๋ฐ์ ์ฌ๋ฐ๋ฅธ ์ค๊ณ๋ฅผ ์ํ ์ฃผ์ ์์น์ ์ ์


