1、裝飾模式
**************************************************************************************************************************
不改變原內容的情況下,通過創建一個包裝對象即裝飾來包裹真實對象,實現保持對象原有功能並動態擴展。
**************************************************************************************************************************
設計原則:多用組合,少用繼承
利用繼承設計子類的行爲,不僅編譯時靜態決定,而且所有子類都會繼承到相同行爲。利用組合擴展對象,可以 在運行時動態擴展。
**************************************************************************************************************************
裝飾模式的特點:
a、裝飾對象和真實對象有相同接口,這樣客戶端對象就能以和真實對象相同的方式和裝飾對象交互。
b、裝飾對象包含一個真實對象的引用(reference)
c、裝飾對象接收所有來自客戶端的請求,並轉發給真實對象
d、裝飾對象可以在轉發請求之前或之後增加一些附屬功能
**************************************************************************************************************************
實用性:(java的io也使用了裝飾者模式)
a、給類增加一個附屬值
b、動態增加功能並能動態撤銷功能
c、小功能的組合排列實現大功能
d、類定義被隱藏或不能被使用時,或拓展功能需要產生大量子類時可用裝飾模式
*************************************************************************************************************************
//定義裝飾者的父類
public abstract class Decorator implements Drink{
public Drink drink; //要裝飾的對象
public Derector(Drink drink){
this.drink = drink;
}
@Override
public String name() {
return drink.name();
}
@Override
public float price() {
return drink.price();
}
}
//定義裝飾者類,椰果類
public class Cocount extends Decorator {
public Cocount(Drink drink) {
super(drink);
}
@Override
public String name () {
return "椰果" + super.name();
}
@Override
pulic float price () {
return super.price() + 0.8f; //椰果0.8元
}
}
//測試裝飾類
public class TestDecorator {
pubic static void main () {
Drink drink = new MakeTea();
Cocount cocount = new Cocount(drink); //奶茶裏添加椰果
System.out.println("第一杯奶茶爲:" + cocount.name() + "價格爲:" + cocount.price());
}
}
2、單例模式
懶漢式單例、餓漢式單例、登記式單例
單例模式特點:
a、只能有一個實例
b、必須創建自己唯一實例
c、必須給其他所有對象提供這一實例
在計算機系統中,線程池、緩存、日誌對象、對話框、打印機、顯卡的驅動程序常被設計成單例。單例模式就是 爲了避免不一致狀態。
*******************************************************************************************************************************
a、懶漢式單例:
第一次調用時,實例化
public class Singleton {
private Singleton() {}
private static Singleton single = null;
public static SIngleton getInstance() { //靜態工廠方法
if(single == null) {
single = new Singleton();
}
return single;
}
} //java反射機制可以實例private的構造方法,這裏不做討論。懶漢式單例模式是線程不安全的。
/est/測試類
public class Tmain {
public static void mian(String[] args) {
TestStream ts1 = TestSingleton.getInstance();
ts1.setName("jason")
TestStream ts2 = TestSingleton.getInstance();
ts2.setName("0593");
ts1.printInfo();
ts2.printInfo();
if(ts1 == ts2) {
System.out.println("創建的是同一個實例");
}else{
System.out.println("創建的不是同一個實例");
}
}
}
//結果-創建的是同一個實例,說明單例模式只會創建一個所有線程公用的實例
b、餓漢式單例模式
private class Singleton {
private Singleton () {}
private static final Singleton single = new Singleton();
public static Singleton getInstance() {
return single;
}
}
c、登記式單例(類似Spring裏面的方法,將類名註冊,下次從裏面直接獲取)
public class Singleton {
private static Map<String,Singleton> map = new HashMap<String,Singleton>();
static{
Singleton single = new Singleton();
map.put(single.getClass().getName(),single);
}
protected Singleton(){}
public static Singleton getInstance(String name){
if(name == null) {
name = Singeton.class.getName();
System.out,println("name == null" + "--->name=" + name );
}
if(map.get(name) == null) {
try{
map.put(name,(Singleton) Class.forName(name).newInstance());
}catch(InstancetiationException e) {
e.printStackTrace();
}catch(IllegalAccessException e) {
e.printStackTrace();
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
return map.get(name);
}
//登記式單例實際上維護了一組單例類的實例,將這些實例存放在一個Map(登記簿)中。已登記過的實例,從Map 直接返回;沒有登記過的,登記後返回。
3、適配器模式(包裝模式)
ocp原則(開閉原則):一個軟件實體應通過擴展增加功能,而不應該通過修改原碼實現變化。
對象適配器模式和類適配器模式(一般多重繼承)
*******************************************************************************************************************************
將一個接口適配成用戶所期待的。適配器允許因爲接口不兼容而不能一起工作的類工作在一起,具體將自己的接 口包裹在一個已存在的類中。
*******************************************************************************************************************************
要求接口中規定了所有要實現的方法,但使用時只實現其中的幾個方法。
*******************************************************************************************************************************
//標準接口
interface Target {
public void request();
}
//Adaptor父類,具有所有功能
class Adaptee {
public void specificRequest() {
System.out.println("配給適配器的特殊功能");
}
}
//適配器類
class Adapter extends Adaptee implements Target {
public void request () {
super.specificRequest();
}
}
//測試類
public class Client {
public static void main(String[] args) {
Target concreteTarget = new Target();
concreteTarget.request(); //普通功能
Target adapter = new Adapeter();
adapter.request(); //適配器特殊功能
}
} //java不支持多線程,只能採用包裝類實現。其實適配器什麼都沒有做,只是將Adaptee和Target黏合在一起,使這 兩者可以通信