设计模式是一些优秀的软件开发人员在开发时经验的积累。它代表了最佳的实践。让我们的代码实现特定的目的,在结构上更加优秀。
一、单例模式
单例模式是指一个类只能有一个实例,不能再创建更多的实例
第一 种是饿汉式
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原则