《head first设计模式》-----笔记(持续跟新)
设计原则:1、把容易变化的抽取出来,使之与变化的分离。
2、是针对接口编程,而不是针对实例编程。(这点很重要,在我所学的工厂模式,以及代理模式还有spring的AOP中都有体现)。
3、对用组合,少用继承。(Java是单继承的程序语言,继承虽然给我们很大的优势,但是在能够用组合的时候最好使用组合。这一点在《think in Java》里也有提到,还有要区分IS-A和HAS-A)。
认识第一个模式:策略模式。
策略模式,其中心思想就是,把变化的部分和不变的部分隔离开来。用接口来“抽取”出来。
用书上的实例吧。如:鸭子,有些鸭子能飞,有些不能飞。我们不能把所有的鸭子都定义成能飞的,反之也是。
所以就用个Flyable(这里是我自己所写的)的接口及其方法fly(),再写两个类CanFly和NoCanFly来实现这个Flyable接口,重写fly()方法。
在鸭子里有定义一个flyable的Flyable属性,并有他setter方法将其实例化。(或许有人疑问,接口能实例化吗?如果我写 Flyable flyable = new CanFly(),这样大家有疑问吗?)。或者用其构造函数将其实例化。现在就达到了一个简单的策略设计模式,达到解耦的作用。或许你的鸭子是使用工具才飞行的,那么你就可以再写一个OtherFly去实现Flyable接口,在里面重写fly()方法,这样的话,你就可以不用修改duck类来得到不同的鸭子了。或许很奇妙,或许很模糊。今天很晚了,所以类图有时间的话,再做出来。
------------------------------------
在这里我学到和巩固了2个知识。
一:在Java编程思想中的向上转型。也就是Flyable flyable = new CanFly()的问题。
二:初始化可以用setter方法或构造函数。不同的情况使用不同的方法。
============================================
总结:一切围绕接口进行。(也可以是抽象类)
我们的第二个模式:
观察者模式。当你的需求出现了一对多的关系的时候,那么请考虑使用这个设计模式,
而此处的一为被观察者也叫做主题,观察者为多。
到主题发生变化的时候你需要所有的观察者都能接受到这个变化。
在JDK 1.5的util包中,给我们提供了一个类observerable及接口observer。
单例模式:
单例模式的定义:只有一个实例存在。
单例模式,可以使用2中方法实现:1、采用static将类修饰,这就使得类在加载的时候jvm就分配了内存模块,不过这样的坏处是,如果类过于庞大的话,占用的空间肯定是很多的。2、定义一个类,然后将其构造方法定义为private,这样外部就不能方法,然后再定义一个返回此类的一个静态方法。当需要调用的时候。调用此方法就可以了。
---------这是第一中定义方法----------
public
class
Singleton(){
//static method
}
//static method
}
---------这是第二中定义方法-----------
1
public
class
Singleton(){
2 private static Singleton singleton;
3 private Sington(){};
4 public static Singleton getInstance(){
5 if (singleton == null ){
6 singleton = new Singleton();
7 } else {
8 return singleton;
9 }
10 }
11 }
2 private static Singleton singleton;
3 private Sington(){};
4 public static Singleton getInstance(){
5 if (singleton == null ){
6 singleton = new Singleton();
7 } else {
8 return singleton;
9 }
10 }
11 }
上面只适合单线程的条件下,如果使用多线程的话,那么必须采用synchronized来修饰方法,使得每个线程进入此方法前都要等待别的线程离开此方法。也就是说不会有2个线程同时进入方法。---------使用synchronized效率不高。
代码:
public
class
Singleton(){
private static synchronized Singleton singleton;
private Sington(){};
public static Singleton getInstance(){
if (singleton == null ){
singleton = new Singleton();
} else {
return singleton;
}
}
}
private static synchronized Singleton singleton;
private Sington(){};
public static Singleton getInstance(){
if (singleton == null ){
singleton = new Singleton();
} else {
return singleton;
}
}
}
如何增加效率呢?
对于jdk 1.5及以后版本使用关键字:volatile
定义代码如下:
public
class
Singleton(){
private volatile static Singleton singleton;
private Sington(){};
public static Singleton getInstance(){
if (singleton == null ){
synchronized (Singleton. class );
if (singleton == null ){
singleton = new Singleton();
}
}
}
return singleton;
}
}
private volatile static Singleton singleton;
private Sington(){};
public static Singleton getInstance(){
if (singleton == null ){
synchronized (Singleton. class );
if (singleton == null ){
singleton = new Singleton();
}
}
}
return singleton;
}
}
重申一下volatile只能在 1.5以上版本才能。
命令模式:
欢迎来到未来城,在未来城里,一切都是用遥控来操控的。现在家里有个Light。其有on 和 off2个方法。(light是操控对象)。
1
package
com.duduli.li.command;
2
3 public class Light {
4 public void on(){
5 System.out.println( " light on! " );
6 }
7 public void off(){
8 System.out.println( " light off " );
9 }
10 }
主要部件Command,一个接口,及其实现了它的2个方法,LightOnCommand和LightOffCommand,代码:
2
3 public class Light {
4 public void on(){
5 System.out.println( " light on! " );
6 }
7 public void off(){
8 System.out.println( " light off " );
9 }
10 }
1
package
com.duduli.li.command;
2
3 public interface Command {
4 public void execute();
5 }
LightOnCommand:
2
3 public interface Command {
4 public void execute();
5 }
1
package
com.duduli.li.command;
2
3 public class LightOnCommand implements Command {
4
5 private Light light;
6
7 public LightOnCommand(Light light){
8 this .light = light;
9 }
10 @Override
11 public void execute() {
12 light.on();
13 }
14 }
2
3 public class LightOnCommand implements Command {
4
5 private Light light;
6
7 public LightOnCommand(Light light){
8 this .light = light;
9 }
10 @Override
11 public void execute() {
12 light.on();
13 }
14 }
LightOffCommand:
1
package
com.duduli.li.command;
2
3 public class LightOffCommand implements Command{
4 private Light light;
5
6 public LightOffCommand(Light light){
7 this .light = light;
8 }
9 @Override
10 public void execute() {
11 light.off();
12 }
13 }
2
3 public class LightOffCommand implements Command{
4 private Light light;
5
6 public LightOffCommand(Light light){
7 this .light = light;
8 }
9 @Override
10 public void execute() {
11 light.off();
12 }
13 }
下来就是遥控器啦
1
package
com.duduli.li.command;
2
3 public class Telecontrol {
4 Command slit;
5
6 public void setCommand(Command command){
7 this .slit = command;
8 }
9
10 public void buttonPressed(){
11 slit.execute();
12 }
13 }
2
3 public class Telecontrol {
4 Command slit;
5
6 public void setCommand(Command command){
7 this .slit = command;
8 }
9
10 public void buttonPressed(){
11 slit.execute();
12 }
13 }
然后则是客户端的调用。
1
package
com.duduli.li.command;
2
3 public class Cient {
4
5 public static void main(String[] args) {
6 Telecontrol tc = new Telecontrol();
7 Light l = new Light();
8 LightOnCommand lon = new LightOnCommand(l);
9
10 tc.setCommand(lon);
11 tc.buttonPressed();
12 }
13 }
2
3 public class Cient {
4
5 public static void main(String[] args) {
6 Telecontrol tc = new Telecontrol();
7 Light l = new Light();
8 LightOnCommand lon = new LightOnCommand(l);
9
10 tc.setCommand(lon);
11 tc.buttonPressed();
12 }
13 }