Java学习--设计模式

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

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原则

猜你喜欢

转载自blog.csdn.net/lyf_0922/article/details/84617128