Java學習--設計模式
阿新 • • 發佈:2018-11-29
設計模式是一些優秀的軟體開發人員在開發時經驗的積累。它代表了最佳的實踐。讓我們的程式碼實現特定的目的,在結構上更加優秀。
一、單例模式
單例模式是指一個類只能有一個例項,不能再建立更多的例項
第一 種是餓漢式
public class Singleton1 { // 讓構造方法私有,別人就沒法建立此類的例項了 private Singleton1() { } //自己建立這個例項 private static final Singleton1 ME = new Singleton1(); //獲取唯一例項 public static Singleton1 getInstance() { return ME; } }
第二種是懶漢式
public class Singleton2 { private Singleton2() { } private static Singleton2 ME; public static synchronized Singleton2 getInstance() { // 當一次呼叫時ME == null為真, 當後續呼叫時ME == null為假,就不會執行建立物件的操作了 if (ME == null) { ME = new Singleton2(); } return ME; } }
上述兩種單例模式的區別在於:
餓漢式是一開始就建立好例項;懶漢式是用時才建立例項
第三種使用列舉實現(餓漢式)
public enum Singleton3 {
ME;
public void m1() {
}
}
第四種使用靜態內部類實現(懶漢式)
public class Singleton4 { private Singleton4() { } // holder 擁有, 由靜態內部類建立了他的唯一例項 private static class Holder { static Singleton4 ME = new Singleton4(); } public static Singleton4 getInstance() { return Holder.ME; } }
注:
破壞單例的辦法:
反射可以呼叫私有構造
反序列化可以破壞單例 (可以阻止)
二、享元模式 flyweight
享元模式是提倡重用已有的物件,而不是建立新的物件。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
三、原型模式 prototype
根據已有物件來建立新的物件, 克隆
使用場景,當物件屬性很多,希望新的物件的大部分屬性從原有物件複製而來。
四、建造器模式 Builder
通過建造起模式可以使建立物件時呼叫構造方法更加靈活。
適用於有多個可省引數的構造方法。
五、迭代器模式 iterator
定義:以一種一致的對集合內的元素進行遍歷,而不用在乎集合內的資料結構
ArrayList 陣列
LinkedList 連結串列
HashSet 陣列+連結串列
TreeSet 二叉搜尋樹-》紅黑樹
六、策略模式 (Strategy)
Java 集合或陣列的排序演算法
基本型別 雙基點快速排序方法
物件型別 TimSort (早期使用歸併排序)
規模小 插入排序
public class TestStrategy {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("zhangsan", 18));
list.add(new Student("lisi", 20));
list.add(new Student("wangwu", 16));
list.add(new Student("zhaoliu", 22));
list.add(new Student("zhaoliu", 20));
// 按年齡拍
Collections.sort(list, (a, b) -> a.getAge() - b.getAge() );
System.out.println(list);
// 按名字拍
Collections.sort(list, (a, b) -> a.getName().compareTo(b.getName()) );
System.out.println(list);
// 先按名字,再按年齡
Collections.sort(list, (a, b) -> {
int x = a.getName().compareTo(b.getName());
if(x != 0) {
return x;
} else {
return a.getAge() - b.getAge();
}
} );
System.out.println(list);
}
}
class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
最後說一下:open close 開閉原則
1.演算法不能改-- 體現的是close原則
2.比較器可以改 – 體現的是open原則