zoukankan      html  css  js  c++  java
  • 学了一招半式策略模式(设计模式)

      博文更新啦。这2天学了一招分享出来,这招式如同 习武之人领悟了上层心法般。
      今天说的是设计模式中经常用到的“策略模式”,概念不说,也不想说,什么是概念,概念就是 让大家理解这个东西是什么意思,可是对于编程理论介绍往往没有实践来的一针见血。
      请耐心听完我说的话,很多朋友以为OOP就是理解了 继承 多态 封装 就够了,对,我承认这些是需要掌握,但是这是理论,这些理论的本质也需要掌握,比如:很多朋友以为  class A:class B,哇,这就是继承,可是 这个是继承吗?继承的本质是啥?继承的优势是什么?继承带来了什么好处?
    就这个问题,我简单介绍下:
    继承本质:你要从 内存机制下手,CLR的托管堆中的GC堆和LOAD堆下手,比如父类的字段在什么位置,比如方法表在什么位置,比如在调用方法的时候是调用什么父类的方法还是子类的方法,这些就是本质?
    我写过一篇博文,对于这个本质说了一点:http://www.cnblogs.com/IAmBetter/archive/2012/02/22/2363485.html

    可是,这是OOP吗,我说了这么一大堆,这些学完了是OOP吗,显然不是?
    例子开始:
     

    abstract class Dog
        {
            /// <summary>
            /// 一些狗公有的特性,跑,啃骨头就省略了
            /// </summary>
            public abstract void Singing();
        }
    
        class RedDog : Dog
        {
            public override void Singing()
            {
                Console.WriteLine("我是红狗,我会汪汪汪汪叫。。。");
            }
    
        }
        class BlackDog : Dog
        {
            public override void Singing()
            {
                Console.WriteLine("我是黑狗,我会哇哇哇哇叫。。。");
            }
        }
    
        class PcDog : Dog
        {
            //可是机器狗不会叫,也继承了怎么办?
    
        }
    



    提示:对,我承认,你利用了 继承 多态 这2个OOP的思想,而且自以为用的还很好,可是问题来了,机器狗不会叫啊,但是也继承了Singing的方法必须实现这个抽象方法,怎么办?
    很多朋友遇到了就会把这个 Singing方法抽象出来,比如抽象成一个接口,然后会叫的狗就实现这个接口。好嘞,修改代码。
     

    interface ISinging
        {
            void Singing();
        }
        abstract class Dog
        {
            /// <summary>
            /// 一些狗公有的特性,跑,啃骨头就省略了
            /// </summary>
           
        }
    
        class RedDog : Dog,ISinging
        {
            public  void Singing()
            {
                Console.WriteLine("我是红狗,我会汪汪汪汪叫。。。");
            }
    
        }
        class BlackDog : Dog,ISinging
        {
            public  void Singing()
            {
                Console.WriteLine("我是黑狗,我会哇哇哇哇叫。。。");
            }
        }
    
        class PcDog : Dog
        {
            //机器狗不会叫,那么我就不实现接口
    
        }
    


    哇,多完美,我用了接口实现了OOP的设计,可是问题来了?如果今天,我开心,我赋予 所有的狗要回飞,于是你又实现了 一个“IFly”的接口。哪天,我要让狗会跳舞,我还得实现“IDance”接口,依次下去。。。。
    看代码:

    interface ISinging
        {
            void Singing();
        }
        interface IFly
        {
            void Fly();
        }
        abstract class Dog
        {
            /// <summary>
            /// 一些狗公有的特性,跑,啃骨头就省略了
            /// </summary>
           
        }
    
        class RedDog : Dog,ISinging,IFly
        {
            public  void Singing()
            {
                Console.WriteLine("我是红狗,我会汪汪汪汪叫。。。");
            }
    
            public void Fly()
            {
                Console.WriteLine("我会飞");
            }
    
        }
        class BlackDog : Dog,ISinging,IFly
        {
            public  void Singing()
            {
                Console.WriteLine("我是黑狗,我会哇哇哇哇叫。。。");
            }
            public void Fly()
            {
                Console.WriteLine("我会飞");
            }
        }
    
        class PcDog : Dog,IFly
        {
            //机器狗不会叫,那么我就不实现接口
            public void Fly()
            {
                Console.WriteLine("我会飞");
            }
    
        }
    



    对,我承认,你利用了接口是完成了客户的需求,可是如果客户是个变态,他需要100000种狗,那么你这个 Fly方法必须写100000次,好庞大的代码量。

    对了,我们说过OOP实现了代码复用,为什么不考虑下能否代码复用呢?

    very good 策略模式的本质出现了:把所有的方法抽象出来,类似于你的接口,然后利用复用代码的特点,节省开发,灵活改变。

    有点领悟没?就是说,你的接口实现,比如一个需求来了,你是为了 完成这个需求(设计)而写代码,这是解决方法,不是思想,而OOP思想是为了 接口编程,为了N多设计,为了N多需求,从一定的高度思考设计框架的一个过程。

    不说废话,开始写:
    思考下:
    狗Singing()方法是吧,如果有2种叫法,一种 哇哇叫,一种汪汪叫,那就抽象出来
    狗还会飞()方法,比如会 低空飞,高空飞。
    把这些会改变的动作抽象出来,把那些不会改变的动作封装起来,一起继承。
     

    /// <summary>
        /// 这是所有Sing的叫法
        /// </summary>
    
        interface ISingable
        {
            void Singing();
            
        }
    
        class WAWA_Sing:ISingable
        {
            public void Singing()
            {
                Console.WriteLine("我会哇哇叫。。。");
            }
        }
        class wangwang_Sing : ISingable
        {
            public void Singing()
            {
                Console.WriteLine("我会汪汪叫。。。");
            }
        }
    
    
        /// <summary>
        /// 这是所有Fly的飞法
        /// </summary>
        ///
    
        interface IFlyable
        {
            void Fly();
        }
        class L_Fly:IFlyable
        {
            public void Fly()
            {
                Console.WriteLine("我会低空飞行");
            }
        }
    
        class H_Fly : IFlyable
        {
            public void Fly()
            {
                Console.WriteLine("我会高空飞行");
            }
            
        }
        abstract class Dog
        {
            /// <summary>
            /// 一些狗公有的特性,跑,啃骨头,是公有的特性不会改变,所以封装起来被继承
            /// </summary>
            ///
            protected ISingable isingable;
            protected IFlyable iflyable;
    
    
            public void PerformSing()
            {
                isingable.Singing();
            }
    
            public void PerformFly()
            {
                iflyable.Fly();
            }
           
        }
    
        class RedDog : Dog
        {
            public RedDog()
            {
                isingable = new WAWA_Sing();
                iflyable = new H_Fly();
            }
    
        }
        class BlackDog : Dog
        {
            public BlackDog()
            {
                isingable = new wangwang_Sing();
                iflyable = new L_Fly();
            }
        }
    


    代码如上:
    1.当还有900个不同的狗 要设计的时候,如何飞,如何叫,只要在这个狗的构造函数内 声明下 是什么叫法类型的对象,是什么飞行类型的对象即可---实现了复用
    2.对于如果没有会飞的狗或者不会叫的狗,必须在写代码前就考虑好。


    这就是策略模式。

    不妨大家可以尝试着,用这个模式 遇到什么设计都用这个模式,练习10几天,然后你自然会总结出 他的优势和缺点。




  • 相关阅读:
    Representation Data in OpenCascade BRep
    Render OpenCascade Geometry Surfaces in OpenSceneGraph
    Render OpenCascade Geometry Curves in OpenSceneGraph
    OpenCascade Shape Representation in OpenSceneGraph
    Geometry Surface of OpenCascade BRep
    Geometry Curve of OpenCascade BRep
    Tyvj2017清北冬令营入学测试
    Spfa算法模板
    洛谷1016 旅行家的预算
    洛谷1290 欧几里得的游戏
  • 原文地址:https://www.cnblogs.com/IAmBetter/p/2429760.html
Copyright © 2011-2022 走看看