设计模式思想:设计模式是为了:增加代码的复用性(一次编码/多处使用),降低代码块之间的耦合度,提高代码块功能的专一性。
我找了几个.pdf文件大家看一下:链接: http://pan.baidu.com/s/1miCUF48 密码: r5f8
IT职场的小菜经常有这样的疑问:
为什么一个相似的功能,大牛一会儿就搞定,然后悠闲地品着下午茶逛淘宝;而自己加班加点搞到天亮还做不完。
为什么用户提出需求变更后,大牛只需潇洒地敲敲键盘,改改配置;而自己将代码改了又改,删了又建,几乎晕厥,最后只能推翻重来。
为什么大牛写完的程序测试上线后,几乎完美运行,用户无懈可击;而自己的程序bug重重,改好一个却又引出另一个,按下葫芦浮起瓢,几近崩溃。
为什么同样是程序员,大牛工资1W,而自己只能拿区区的3K?
大牛显然知道一些小菜所不知道的秘密,这秘密又是什么呢?
这个秘密就是设计模式。设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。只有精通了设计模式,才敢说真正理解了软件工程。可以说,设计模式是每一个架构师所必备的技能之一。作为一个面向对象设计程序员,只有精通了设计模式,才能完成自身价值从3K到1W的飞跃,才能摆脱码奴的命运,成为一个真正的软件工程师。
一个程序员对设计模式的理解:
“不懂”为什么要把
很简单的东西搞得那么复杂。后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的
“简单”就是一把钥匙开一把锁的模式,目的仅仅是着眼于解决现在的问题,而设计模式的“复杂”就在于它是要构造一个“万能钥匙”,目的是提出一种对所有锁的开锁方案。在真正理解设计模式之前我一直在编写“简单”的代码.
这个
“简单”不是功能的简单,而是设计的简单。简单的设计意味着缺少灵活性,代码很钢硬,只在这个项目里有用,拿到其它的项目中就是垃圾,我将其称之为
“一次性代码”。
-->要使代码可被反复使用,请用'设计模式'对你的代码进行设计.
还有人甚至把是否了解设计模式作为程序员划分水平的标准。
我们也不能陷入模式的陷阱,为了使用模式而去套模式,那样会陷入形式主义。我们在使用模式的时候,一定要注意模式的意图(intent),而不 要过多的去关注模式的实现细节,因为这些实现细节在特定情况下,可能会发生一些改变。不要顽固地认为设计模式一书中的类图或实现代码就代表了模式本身。
一、设计模式的分类
总体来说设计模式分为三大类:
1)创建型模式(5):
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
2)结构型模式(7):
适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
3)行为型模式(11):
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
4)还有两类(2):并发型模式和线程池模式。
另外一种分类方式:
二、设计模式的六大原则
1)开闭原则(Open Close Principle)
对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果(允许用户在不关闭系统,不切断电源的情况下取出和更换损坏的硬盘、电源或板卡等部件,从而提高了系统对灾难的及时恢复能力、扩展性和灵活性等)。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
2)里氏代换原则(Liskov Substitution Principle)
里氏代换原则面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
3)依赖倒转原则(Dependence Inversion Principle)
这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。
4)接口隔离原则(Interface Segregation Principle)
这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。
5)迪米特法则(最少知道原则)(Demeter Principle)
为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
6)合成复用原则(Composite Reuse Principle)
原则是尽量使用合成/聚合的方式,而不是使用继承。
、首先来看设计模式思想
1)单例模式:(单例对象能保证在一个 JVM 中,该对象只有一个实例存在/常用)(懒汉式单例/饿汉式单例):
A:保证类在内存中只有一个对象
B:构造方法私有化
C:单例类必须自己创建自己的唯一实例
D:单例类必须给所有其他对象提供这一实例
E:单例有并发问题,只有一个实例,多个线程就可能同时或不同时访问它,那么它的状态(属性成员)的一致性就是个问题,写入状态的方法必须同步。
单例模式的应用:
在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。
spring配置文件bean默认singleton=true,在spring的beanfactory当中这个bean实例只有一个。
在GoF中的单例模式是指一个ClassLoader中只存在类一个实例。
而在Spring中的单例实际上更确切的说应该是:
1.每个Spring Container中定义的Bean只存在一个实例
2.每个Bean定义只存在一个实例。
A:饿汉式单例模式(线程安全):在类的初始化的时候自行实例化
1. public class Singleton {
2. //私有化构造方法
3. private Singleton(){}
4. //自己创建自己的唯一实例
5. private static Singleton instance = new Singleton();
6.
7. //使用对象的调用方法
8. public static Singleton getInstance() {
9. return instance;
10. }
11. //调用
12. Singleton singleton= Singleton.getInstance();
13. }
a:开发时使用(一种不会出问题的单例模式)
1. public class Singleton {
2.
3. // 私有默认构造
4. private Singleton() {
5. }
6.
7. //自己创建自己的唯一实例
8. private static final Singleton single = new Singleton();
9.
10. //静态工厂方法
11. public static Singleton getInstance() {
12. return single;
13. }
14. //调用
15. Singleton singleton= Singleton.getInstance();
16. }
B:懒汉式单例模式(线程不安全):在第一次调用的时候实例化自己
a:懒加载(延迟加载)
b:线程安全问题
1. public class Singleton {
2.
3. // 私有的默认构造子
4. private Singleton() {
5. }
6.
7. //注意,这里没有final
8. private static Singleton single = null;
9.
10. //静态工厂方法
11. public synchronized static Singleton getInstance() {
12. if (single == null) {
13. new Singleton();
14. }
15. return single;
16. }
17. //调用
18.
19. }
2) 工厂设计模式(黑盒模式):(提供创建对象的接口/常用)==>简单工厂(一对一)==>工厂方法(一对多)==>抽象工厂(多对多)
A:简单工厂模式 = (车)接口+(奥迪)子类方法+(宝马)子类方法+(工厂)生产对象+Test测试方法
B:工厂方法模式= (车)接口+(奥迪)子类方法+(宝马)子类方法+(工厂)接口+(宝马工厂)具体工厂+(奥迪工厂)具体工厂+Test测试方法
C:抽象工厂模式=(奥迪)接口+(跑车奥迪)子类方法+(商务奥迪)子类方法+(宝马)接口+(跑车宝马)子类方法+(商务宝马)子类方法+(工厂(2个抽象方法))接口+(运动奥迪)具体工厂+(商务奥迪)具体工厂+(运动宝马)具体工厂+(商务宝马)具体工厂+Test测试方法
适用性: 当一个类不知道它所必须创建的对象的类的时候。
A:简单工厂模式:
1. //抽象产品
2. abstract class
3. private
4.
5. public abstract void
6.
7. public
8. return
9. }
10. public void
11. this.name = name;
12. }
13. }
14. //具体产品
15. class Benz extends
16. public void
17. this.getName()+"----go-----------------------");
18. }
19. }
20.
21. class Bmw extends
22. public void
23. this.getName()+"----go-----------------------");
24. }
25. }
26.
27. //简单工厂
28. class
29. public static
30. null;
31. if("Benz".equalsIgnoreCase(car))
32. new
33. else if("Bmw".equalsIgnoreCase(car))
34. new
35. return
36. }
37. }
38.
39. //老板
40. public class
41.
42. public static void main(String[] args) throws
43. //老板告诉司机我今天坐奔驰
44. "benz");
45. "benz");
46. //司机开着奔驰出发
47. car.drive();
48. }
B:工厂方法模式:
1. //抽象产品
2. abstract class
3. private
4.
5. public abstract void
6.
7. public
8. return
9. }
10. public void
11. this.name = name;
12. }
13. }
14. //具体产品
15. class Benz extends
16. public void
17. this.getName()+"----go-----------------------");
18. }
19. }
20. class Bmw extends
21. public void
22. this.getName()+"----go-----------------------");
23. }
24. }
25.
26.
27. //抽象工厂
28. abstract class
29. public abstract Car createCar(String car) throws
30. }
31. //具体工厂(每个具体工厂负责一个具体产品)
32. class BenzDriver extends
33. public Car createCar(String car) throws
34. return new
35. }
36. }
37. class BmwDriver extends
38. public Car createCar(String car) throws
39. return new
40. }
41. }
42.
43. //老板
44. public class
45.
46. public static void main(String[] args) throws
47. new
48. "benz");
49. "benz");
50. c.drive();
51. }
52. }
为了提高程序的可拓展性和后期的可维护性,我们选择工厂模式是非常正确的。
C:抽象工厂模式:(一般用于具有产品树和产品族的场景下)
1. //抽象产品(Bmw和Audi同理)
2. abstract class
3. private
4.
5. public abstract void
6.
7. public
8. return
9. }
10. public void
11. this.name = name;
12. }
13. }
14. //具体产品(Bmw和Audi同理)
15. class BenzSportCar extends
16. public void
17. this.getName()+"----BenzSportCar-----------------------");
18. }
19. }
20. class BenzBusinessCar extends
21. public void
22. this.getName()+"----BenzBusinessCar-----------------------");
23. }
24. }
25.
26. abstract class
27. private
28.
29. public abstract void
30.
31. public
32. return
33. }
34. public void
35. this.name = name;
36. }
37. }
38. class BmwSportCar extends
39. public void
40. this.getName()+"----BmwSportCar-----------------------");
41. }
42. }
43. class BmwBusinessCar extends
44. public void
45. this.getName()+"----BmwBusinessCar-----------------------");
46. }
47. }
48.
49. abstract class
50. private
51.
52. public abstract void
53.
54. public
55. return
56. }
57. public void
58. this.name = name;
59. }
60. }
61. class AudiSportCar extends
62. public void
63. this.getName()+"----AudiSportCar-----------------------");
64. }
65. }
66. class AudiBusinessCar extends
67. public void
68. this.getName()+"----AudiBusinessCar-----------------------");
69. }
70. }
71.
72.
73. //抽象工厂
74. abstract class
75. public abstract BenzCar createBenzCar(String car) throws
76.
77. public abstract BmwCar createBmwCar(String car) throws
78.
79. public abstract AudiCar createAudiCar(String car) throws
80. }
81. //具体工厂
82. class SportDriver extends
83. public BenzCar createBenzCar(String car) throws
84. return new
85. }
86. public BmwCar createBmwCar(String car) throws
87. return new
88. }
89. public AudiCar createAudiCar(String car) throws
90. return new
91. }
92. }
93. class BusinessDriver extends
94. public BenzCar createBenzCar(String car) throws
95. return new
96. }
97. public BmwCar createBmwCar(String car) throws
98. return new
99. }
100. public AudiCar createAudiCar(String car) throws
101. return new
102. }
103. }
104.
105. //老板
106. public class
107.
108. public static void main(String[] args) throws
109.
110. new
111. "");
112. car.drive();
113. }
114. }
工厂方法模式与抽象工厂模式区别:
A:工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
B:工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
小结:
A:简单工厂模式:一个工厂只生产一类的产品
B:工厂方法模式:一个工厂生产不同的产品
C:抽象工厂模式:多个工厂生产不同的产品
3)观察者模式:(当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化)
4)状态模式:QQ有几种状态,在线、隐身、忙碌等,每个状态对应不同的操作
1、可以通过改变状态来获得不同的行为。
2、你的好友能同时看 到你的变化。
5)策略模式:(锦囊妙计)1个锦囊+3个妙计+执行者赵云+诸葛亮
策略模式封装了变化:商场促销(打折,返现,周年庆等)
6) 代理模式:[潘金莲->王婆->西门庆]/[职员->代理(秘书)->经理]
代理人必须知道被代理人能够做什么(继承同接口)
7)适配器模式:电源适配器(中国/日本电源电压不同220v/110v转换为你需要的36v)