zoukankan      html  css  js  c++  java
  • 深入浅出设计模式【转载】

    oreilly的《Head.First设计模式》,《深入浅出设计模式》是一本好书,用生动的语言讲解设计模式。而且是逐级深入,并没有一上来就gof23,就一大套设计模式的理论。而是用例子切入,使得读者逐步的理解设计模式的好处,理解设计模式可以解决的问题,使我们有了继续读下去的理由和勇气,而不至于被大片的理论所击倒。

    更加容易入门,为以后读那些理论打下坚实的基础。

    感谢作者写出一本这么好的书。

    设计原则一:

    找出应用中可能需要变化的地方,把他们独立出来,不要和那些不需要变化的代码混合在一起。

    把会变化的部分取出来“封装”起来,以便以后可以轻易的修改和扩展此部分,而不会影响不需要变化的部分。

    单一职责原则。

    设计原则二:

    针对接口编程,而不是针对实现编程。

    针对接口编程,这里的接口是广义的接口,不止包括语法中的接口interface


    public interface IFlyBehavior

       {

           void Fly ();

       }

    还包括抽象类,其实就是一个超类型,反正不是具体的实现类,这样就可以利用多态,不会被绑死到一种具体的类型和实现上。这句话也可以解释为变量的声明应该是超类型,通常是一个抽象类或者是一个接口,因此只要是实现了超类的具体类产生的对象,都可以赋值给这个变量。


    public abstract class Animal

        {

            public abstract void MakeSound();

        }

        public class Dog : Animal

        {

            public override void MakeSound()

            {

                bark();

            }

            public void bark()

            { }

        }

        public class Cat : Animal

        {

            public override void MakeSound()

            {

                meow();

            }

            public void meow()

            { }

        }

    针对实现编程的调用代码


     public void Caller1()

            {

                Dog dog = new Dog();

                dog.bark();

            }

    针对接口编程的调用代码


     public void Caller2()

            {

                Animal a = new Cat();

                a.MakeSound();

            }

    在上面的代码中Animal a new Cat();动物的创建还是被硬编码了,我们还可以在代码运行的时候再来指定创建的类型,就是我们不关心创建的类型是什么,只要可以进行makesound就可以了。方法有很多,常见的就是利用一个工厂类,将对象的创建交给工程类来完成,只要告诉它需要创建的对象的特征即可。这里我们简单的使用对象的类型名称代表对象。

    简单工厂类

     

    public class AnimalFactory

        {

            public static Animal CreateAnimal(string type)

            {

                switch (type)

                {

                    case "dog":

                        return new Dog();

                        break;

                    case "cat":

                        return new Cat();

                        break;

                    default:

                        return null;

                        break;

                }

            }

        }

    调用方


     public void Caller3()

            {

                Animal a = AnimalFactory .CreateAnimal ("cat");

                a.MakeSound();

            }

    但是我们还是在工厂方法中看到了switch或者是很多的if。。。else。。。,如果有新类型添加,这个静态方法还是要不断的添加,越来越长,就会不符合OPC原则,有什么更好的办法吗?

    答案是:有。

    我们可以将系统现有的类型都预先创建出来,然后再外部调用静态方法的时候,给他需要的对象就可以了。

     

     public class AnimalFactory

        {

            private Dictionary<string, Animal> _animals;

            private AnimalFactory()

            {

                _animals = new Dictionary<string, Animal>();

                _animals.Add("dog"new Dog());

                _animals.Add("cat"new Cat());

            }

            private static AnimalFactory _instance = new AnimalFactory();

            private static  object _lockObj = new object();

            public static AnimalFactory GetInstance()

            {

                if (_instance == null)

                {

                    lock (_lockObj)

                    {

                        if (_instance == null)

                            _instance = new AnimalFactory();

                    }

                }

                return _instance;

            }

            public  Animal CreateAnimal(string type)

            {

                return _animals[type];

                //switch (type)

                //{

                //    case "dog":

                //        return new Dog();

                //        break;

                //    case "cat":

                //        return new Cat();

                //        break;

                //    default:

                //        return null;

                //        break;

                //}

            }

        }

    调用方代码


     public void Caller3()

            {

                Animal a = AnimalFactory.GetInstance () .CreateAnimal ("cat");

                a.MakeSound();

            }

    我们先创建一个字典,作为容器,预先放置了全部的类型及其类型名称,然后再需要的时候取一个出来就可以了。如果有新类型添加,也不用每次都添加一个if或者是case了,只要修改工厂方法的静态构造函数,在字典中添加新元素就可以了。

    这时候有些人会觉得这里好像很眼熟,对了,就是容器,IOC容器,依赖注入,我们不知不觉的重构到了IOC容器。IOC容器就是一个类似字典的东西,使得你事先可以注册很多的类型在里面,设置好这些类型的映射关系,配置好容器之后,容器中就会有很多的类型实例,然后再用容器的Resolv方法来获取指定类型的实例,而不用new方法来创建了。

    而且上面最后的工厂类,我们还使用了单件模式以及简单工厂模式。

    类型的注册可以采用代码编写,就好像向字典中添加元素一样。也可以采用xml配置文件,更加灵活。

    源文档 <http://www.cnblogs.com/virusswb/archive/2010/07/01/Head-First-Studying-Note-1.html>

    不管遇到什么样的困难,一定要坚持,即便是嘴里唠叨着累、烦、想放弃,心里还是要默默的给自己说:再试试看再坚持一次。等时间时间久了回头看看原来自己战胜了很多次,原来自己是可以的,坚持坚持就好了。
  • 相关阅读:
    迭代加深搜索 codevs 2541 幂运算
    二叉树结构 codevs 1029 遍历问题
    深搜+DP剪枝 codevs 1047 邮票面值设计
    2016.6.10 深度优先搜索练习
    二分+动态规划 POJ 1973 Software Company
    tarjan算法求桥双连通分量 POJ 3177 Redundant Paths
    tarjan算法+缩点:求强连通分量 POJ 2186
    tarjan算法求割点cojs 8
    关键路径 SDUTOJ 2498
    第二章 STM32的结构和组成
  • 原文地址:https://www.cnblogs.com/hexiaoping/p/1812988.html
Copyright © 2011-2022 走看看