本帖最后由 惜 于 2018-12-21 10:50 编辑  
 
一、  "开放-封闭"原则(OCP)  
 Open-Closed Principle 原则讲的是:一个软件实体应当对扩展开放,对修改关闭。 
优点:通过扩展已有软件系统,可以提供新的行为,以满足对软件的新的需求,使变化中的软件有一定的适应性和 
灵活性。已有软件模块,特别是最重要的抽象层模块不能再修改,这使变化中的软件系统有一定的稳定性和延续性。 
例子:玉帝招安美猴王  
当年大闹天宫便是美猴王对玉帝的新挑战。美猴王说:"'皇帝轮流做,明年到我家。'只教他搬出去,将天宫让于 我!"对于这项挑战,太白金星给玉皇大帝提出的建议是:"降一道招安圣旨,宣上界来…,一则不劳师动众,二则 收仙有道也。"   
换而言之,不劳师动众、不破坏天规便是"闭",收仙有道便是"开"。招安之道便是玉帝天庭的"开放-封闭"原则。  
招安之法的关键便是不允许更改现有的天庭秩序,但允许将妖猴纳入现有秩序中,从而扩展了这一秩序。用面向 
对象的语言来讲,不允许更改的是系统的抽象层,而允许更改的是系统的实现层。  
  
二、  里氏代换原则(LSP)  
 
 
Liskov Substitution Principle(里氏代换原则):子类型(subtype)必须能够替换它们的基类型。  
 
 
 
 
人骑马 骑白马 骑黑马。反过来的代换不成立。 
 
 
《墨子·小取》说:"娣,美人也,爱娣,非爱美人也……"娣便是妹妹,哥哥喜爱妹妹,是因为两人是兄妹关系, 
而不是因为妹妹是个美人。因此,喜爱妹妹不等同于喜爱美人。用面向对象语言描述,美人是基类,妹妹是美人 
的子类。哥哥作为一个有"喜爱()"方法,接受妹妹作为参数。那么,这个"喜爱()"方法一般不能接受美人的实例。  
 
 
 
 
以下代码示例:长方形和正方形 
[C#] 纯文本查看 复制代码     /// <summary>
    /// 长方形
    /// </summary>
    public class Rectangle
    {
        private int width;
        private int height;
        public virtual void setWidth(int width)
        {
            this.width = width; 
        }
        public virtual void setHeight(int height)
        {
            this.height = height;
        }
        public virtual int getWidth()
        {
            return this.width;
        }
        public virtual int getHeight()
        {
            return this.height;
        }
    }
    /// <summary>
    /// 正方形
    /// </summary>
    public class Square : Rectangle
    {
        public int Side { set; get; }
        public override void setWidth(int width)
        {
            this.Side = width;
        }
        public override void setHeight(int height)
        {
            this.Side = height;
        }
        public override int getWidth()
        {
            return this.Side;
        }
        public override int getHeight()
        {
            return this.Side;
        }
       
    }
    public class SmartTest
    {
        public void resize(Rectangle r)
        {
            while (r.getHeight() >= r.getWidth())
            {
                r.setWidth(r.getWidth() + 1); 
                Console.WriteLine(r.getWidth());
            }
            Console.ReadLine();
        }
    }
        static void Main(string[] args)
        {
            SmartTest t = new SmartTest();
            t.resize(new Square() { Side = 100 });
        } 
 
在执行 SmartTest 的 resize 方法时,如果传入的是长方形对象,当高度大于宽度时,会自动增加宽度直到超 
出高度。但是如果传入的是正方形对象,则会陷入死循环。正方形不可以做长方形的子类。 
 
重构类:让长方形和正方形,都继承四边形属性。形成自己独特的方法。 
 
 |