《head first設(shè)計(jì)模式》-----筆記(持續(xù)跟新)
設(shè)計(jì)原則:1、把容易變化的抽取出來(lái),使之與變化的分離。
2、是針對(duì)接口編程,而不是針對(duì)實(shí)例編程。(這點(diǎn)很重要,在我所學(xué)的工廠模式,以及代理模式還有spring的AOP中都有體現(xiàn))。
3、對(duì)用組合,少用繼承。(Java是單繼承的程序語(yǔ)言,繼承雖然給我們很大的優(yōu)勢(shì),但是在能夠用組合的時(shí)候最好使用組合。這一點(diǎn)在《think in Java》里也有提到,還有要區(qū)分IS-A和HAS-A)。
認(rèn)識(shí)第一個(gè)模式:策略模式。
策略模式,其中心思想就是,把變化的部分和不變的部分隔離開(kāi)來(lái)。用接口來(lái)“抽取”出來(lái)。
用書(shū)上的實(shí)例吧。如:鴨子,有些鴨子能飛,有些不能飛。我們不能把所有的鴨子都定義成能飛的,反之也是。
所以就用個(gè)Flyable(這里是我自己所寫(xiě)的)的接口及其方法fly(),再寫(xiě)兩個(gè)類(lèi)CanFly和NoCanFly來(lái)實(shí)現(xiàn)這個(gè)Flyable接口,重寫(xiě)fly()方法。
在鴨子里有定義一個(gè)flyable的Flyable屬性,并有他setter方法將其實(shí)例化。(或許有人疑問(wèn),接口能實(shí)例化嗎?如果我寫(xiě) Flyable flyable = new CanFly(),這樣大家有疑問(wèn)嗎?)。或者用其構(gòu)造函數(shù)將其實(shí)例化。現(xiàn)在就達(dá)到了一個(gè)簡(jiǎn)單的策略設(shè)計(jì)模式,達(dá)到解耦的作用。或許你的鴨子是使用工具才飛行的,那么你就可以再寫(xiě)一個(gè)OtherFly去實(shí)現(xiàn)Flyable接口,在里面重寫(xiě)fly()方法,這樣的話(huà),你就可以不用修改duck類(lèi)來(lái)得到不同的鴨子了。或許很奇妙,或許很模糊。今天很晚了,所以類(lèi)圖有時(shí)間的話(huà),再做出來(lái)。
------------------------------------
在這里我學(xué)到和鞏固了2個(gè)知識(shí)。
一:在Java編程思想中的向上轉(zhuǎn)型。也就是Flyable flyable = new CanFly()的問(wèn)題。
二:初始化可以用setter方法或構(gòu)造函數(shù)。不同的情況使用不同的方法。
============================================
總結(jié):一切圍繞接口進(jìn)行。(也可以是抽象類(lèi))
我們的第二個(gè)模式:
觀察者模式。當(dāng)你的需求出現(xiàn)了一對(duì)多的關(guān)系的時(shí)候,那么請(qǐng)考慮使用這個(gè)設(shè)計(jì)模式,
而此處的一為被觀察者也叫做主題,觀察者為多。
到主題發(fā)生變化的時(shí)候你需要所有的觀察者都能接受到這個(gè)變化。
在JDK 1.5的util包中,給我們提供了一個(gè)類(lèi)observerable及接口observer。
單例模式:
單例模式的定義:只有一個(gè)實(shí)例存在。
單例模式,可以使用2中方法實(shí)現(xiàn):1、采用static將類(lèi)修飾,這就使得類(lèi)在加載的時(shí)候jvm就分配了內(nèi)存模塊,不過(guò)這樣的壞處是,如果類(lèi)過(guò)于龐大的話(huà),占用的空間肯定是很多的。2、定義一個(gè)類(lèi),然后將其構(gòu)造方法定義為private,這樣外部就不能方法,然后再定義一個(gè)返回此類(lèi)的一個(gè)靜態(tài)方法。當(dāng)需要調(diào)用的時(shí)候。調(diào)用此方法就可以了。
---------這是第一中定義方法----------
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 }
上面只適合單線(xiàn)程的條件下,如果使用多線(xiàn)程的話(huà),那么必須采用synchronized來(lái)修飾方法,使得每個(gè)線(xiàn)程進(jìn)入此方法前都要等待別的線(xiàn)程離開(kāi)此方法。也就是說(shuō)不會(huì)有2個(gè)線(xiàn)程同時(shí)進(jìn)入方法。---------使用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;
}
}
}
如何增加效率呢?
對(duì)于jdk 1.5及以后版本使用關(guān)鍵字: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以上版本才能。
命令模式:
歡迎來(lái)到未來(lái)城,在未來(lái)城里,一切都是用遙控來(lái)操控的。現(xiàn)在家里有個(gè)Light。其有on 和 off2個(gè)方法。(light是操控對(duì)象)。
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,一個(gè)接口,及其實(shí)現(xiàn)了它的2個(gè)方法,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 }
下來(lái)就是遙控器啦
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 }
然后則是客戶(hù)端的調(diào)用。
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 }
posted on 2008-11-22 11:20 duduli 閱讀(2062) 評(píng)論(4) 編輯 收藏 所屬分類(lèi): 設(shè)計(jì)模式