说不屑一顾,并不是说设计模式没有屌用,反而,我对总结出这套理论的大牛们心存感激亦存尊重。我想表达的是,“设计”,“模式”这两个词看起来似乎很高大上,好像自己沾点边那就跟架构师乃至技术总监相隔不远了,但却并不如大家想象的那样遥远和高深。
我面过一些人,也被很多人面过,在面试java时设计模式是很常见的话题,很遗憾的是,几乎所有人讨论的都是设计模式本身,诸如:你用过哪些设计模式啊?原理什么样的?画个类图看看?使用场景有哪些?门面模式和代理模式有什么区别等等。我曾经遇见过一位同事,可以说是个技术面很广的人,你随便说个技术名词能跟你讲一大堆,23种设计模式你随便挑一个,他都能准确的帮你把概念,类图,优缺点,适用于哪些场景“背”出来。但是看过他的代码后,我很悲哀。
在我认为,真正懂得设计模式的人,是不需要去记那些繁琐的名词以及概念的,因为“设计模式”对他们来说是“不屑”的(除非他刻意去记)。因为:
1.设计模式只是一些优秀经验的积累,
举个栗子:老板说要模拟一个小孩哭的场景,这小孩一哭就哇哇哇。
报告老板,写完了。
public class Baby { public void cry() { System.out.println("wa wa wa!"); } }
老板又说了,家里有条狗,小孩一哭,狗也跟着叫。
好吧,改一改,先加条狗:
public class Dog { public void bark() { System.out.println("汪汪汪!"); } }
然后,小孩一哭,狗就跟着叫
public class Baby { private Dog dog; public void cry() { System.out.println("哇哇哇!"); if (dog != null) dog.bark(); } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } }
老板又说了,主人还养了猫,猫也跟着叫
好,再改
public class Cat { public void bark() { System.out.println("喵喵喵!"); } } public class Baby { private Dog dog; private Cat cat; public void cry() { System.out.println("哇哇哇!"); if (dog != null) dog.bark(); if (cat != null) cat.bark(); } // getter and setter }
老板又说了,还有鸡,鸡还不少,好多只。
如果你还认为要这样继续加下去我觉得你是一个不合格的程序猿,我相信大部分人肯定会寻思怎么改了,怎么更容易让老板的需求变得容易实现:
先抽象一个动物,dog和cat直接实现它
public interface Animal { void bark(); } public class Cat implements Animal { public void bark() { System.out.println("喵喵喵!"); } } public class Dog implements Animal { public void bark() { System.out.println("汪汪汪!"); } }
然后改Baby
public class Baby { private List<Animal> animals = new ArrayList<Animal>(); public void cry() { System.out.println("哇哇哇!"); for (Animal animal : animals) { animal.bark(); } } public void addAnimal(Animal animal) { animals.add(animal); } // getter and setter }
现在好了,老板,你家爱有多少动物就有多少吧。
我相信任何一个不懂设计模式的程序猿,稍微有些工作经验,只要有心优化这段代码,不想再被老板无休止得加动物而烦恼,这段代码写出来并不难,而这就是23种设计模式中的监听者模式。即使你连设计模式是什么也不知道,只要有心写上若干年,某天突然来看,你会发现,几乎所有的设计模式你都用过。
2.设计模式更多的只是一种思想,而不在于代码
再举个例子,还是小孩哭,小孩一哭妈妈就喂奶。某某对于设计模式非常“精通”,于是这样写:
public interface IMother { void nurse(); } public class Mother implements IMother { public void nurse() { System.out.println("乖宝宝别哭!"); } } public class Baby { private List<Mother> mothers = new ArrayList<Mother>(); public void cry() { System.out.println("哇哇哇!"); for (Mother mother : mothers) { mother.nurse(); } } public void addMother(Mother mother) { mothers.add(mother); } // getter and setter }
不好意思,老板,作为一个老司机,你所有的需求变化都在我的预料之中,随便你怎么变,我都能满足你,因为我用了设计模式中的监听者模式!!
老板:你他妈脑袋有包,小孩能有几个妈???
spring mvc的controller,service类并没有要求写成单例模式,也没有写工厂,但是实际上这些类spring都是生成的单例,而且所有实例统一管控。这不正是单例模式和工厂模式的思想么?当你真正明白这些思想时,并不会拘泥于这些模式。
另外也说一点,真正好的设计,并不是基于你用了多少设计模式,而是基于你对当前业务和业务扩展性的理解,非要把一些不会扩展的地方写成松耦合,滥用设计模式,只会导致工作量增加和类泛滥!
所以,请所有的面试官们,如果你仍然为自己“懂”那么多设计模式而感觉高高在上,请停止你那些愚蠢的提问,因为很可能一个真正的程序猿就被你的无知给筛掉了。
设计模式体现在每一行追求完美的代码中,而我们无须追寻!
谨以此文献给那些总在力求让自己的代码更加优美,更加易于业务扩展的程序猿们。