設計原則:
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類來得到不同的鴨子了?;蛟S很奇妙,或許很模糊。今天很晚了,所以類圖有時間的話,再做出來。
------------------------------------
在這里我學到和鞏固了2個知識。
一:在Java編程思想中的向上轉型。也就是Flyable flyable = new CanFly()的問題。
二:初始化可以用setter方法或構造函數。不同的情況使用不同的方法。
============================================
總結:一切圍繞接口進行。(也可以是抽象類)
我們的第二個模式:
觀察者模式。當你的需求出現了一對多的關系的時候,那么請考慮使用這個設計模式,
而此處的一為被觀察者也叫做主題,觀察者為多。
到主題發生變化的時候你需要所有的觀察者都能接受到這個變化。
在JDK 1.5的util包中,給我們提供了一個類observerable及接口observer。
單例模式:
單例模式的定義:只有一個實例存在。
單例模式,可以使用2中方法實現:1、采用static將類修飾,這就使得類在加載的時候jvm就分配了內存模塊,不過這樣的壞處是,如果類過于龐大的話,占用的空間肯定是很多的。2、定義一個類,然后將其構造方法定義為private,這樣外部就不能方法,然后再定義一個返回此類的一個靜態方法。當需要調用的時候。調用此方法就可以了。
---------這是第一中定義方法----------
public class Singleton(){
//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 }
上面只適合單線程的條件下,如果使用多線程的話,那么必須采用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;
}
}
}
如何增加效率呢?
對于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;
}
}
重申一下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,代碼:
1 package com.duduli.li.command;
2
3 public interface Command {
4 public void execute();
5 }
LightOnCommand:
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 }
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 }
下來就是遙控器啦
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 }
然后則是客戶端的調用。
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 }