面試三種設計模式
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黏合在一起,使這 兩者可以通訊