设计模式

设计模式

编程中的一些套路,让我们的代码实现特定的目的,是结构上更加高效

单例模式

虚拟机中的这个类只有一个实例(一个对象)

实现方法

1.饿汉式单例模式

先定义静态实例

public class Singleton1 {
    //将构造方法私有
    private Singleton1(){

    }
    //创建单例
    private static final Singleton1 ME = new Singleton1();
    //得到单例对象
    public static Singleton1 getMe(){
        return ME;
    }
}

测试一下

public class TestSingle {
    public static void main(String[] args) {
        //构造方法私有不能通过构造创建
        Singleton1 s1 = Singleton1.getMe();
        Singleton1 s2 = Singleton1.getMe();
        
        //比较两个对象的地址值
        System.out.println(s1==s2);
    }
}

2.懒汉式单例模式

先定义引用

public class Singleton2 {
    private  Singleton2(){

    }
    //仅仅只创建引用
    private static Singleton2 ME;
    //再多线程环境下,有可能会创建出多个单例
    //因此需要同步
    public static synchronized Singleton2 getME(){
       if(ME==null){
            ME = new Singleton2();
        }
        return ME;
    }
}

测试一下

public class TestSingle {
    public static void main(String[] args) {
        Singleton2 s1 = Singleton2.getME();
        Singleton2 s2 = Singleton2.getME();
        //比较地址值
        System.out.println(s1==s2);
    }
}

3.枚举实现单例模式

通过枚举特性实现,也算是饿汉式单例

    public enum Singleton3{
        ME;
    }

4.静态内部类改善后的懒汉式单例

public class Singleton4 {
    static {
        System.out.println(" Singleton4");
    }
    private Singleton4(){
        
    }
    //创建唯一实例
    private static class Holder{
         static {
                System.out.println(" Singleton4 Holder"); 
         }
        static Singleton4 ME = new Singleton4();
    }
    
    public static Singleton4 getME(){
         
        return Holder.ME;
    }
    static{
                 System.out.println("Singleton4 getME"); 
    }
}

破坏单例

1.反射可以调用似有构造(不能阻止)
2.反序列化可以破坏单例(可以阻止 大家可以自己去看)

享元模式(FlyWeight)

提倡重用已有的对象,而不是创建新的对象。

比如Interger中的valueOf()方法

    /* public static Integer valueOf(int i) {
    *        if (i >= IntegerCache.low && i <= IntegerCache.high)
    *            return IntegerCache.cache[i + (-IntegerCache.low)];
    *        return new Integer(i);
    *    }
    */

享元范围 -127 - 128

原型模式 prototype

根据已有的对象来创建新的对象,克隆

适合当对象属性很多,希望新对象的属性和已有对象的属性相同的情况

实现方法

    public class User implements Cloneable{
        private String name;
        private int age;
    
        public User() {
            
        }
        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
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }

测试代码

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        User user = new User();
        user.setAge(18);
        user.setName("Mike");
        
        User user1 = (User)user.clone();

        System.out.println(user == user1);

        System.out.println(user1.getAge() + user1.getName());
    }
}

深拷贝和浅拷贝

1.使用Cloneable实现的是浅拷贝,只是复制了地址,里面的内容并不是全新的
2.通过序列化和反序列化流实现

import java.io.*;
import java.util.Date;

public class User2 implements Cloneable, Serializable {

    private String name;
    private int age; // 18  --> 18
    private Date birthday; // #1234  --> #1234

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    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
    protected Object clone() throws CloneNotSupportedException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            // 把自己(当前对象)写入输出流
            new ObjectOutputStream(os).writeObject(this);

            // 拿到字节数组
            byte[] bytes = os.toByteArray();

            // 反序列化为新对象
            ByteArrayInputStream is = new ByteArrayInputStream(bytes);

            // 对象输入流
            ObjectInputStream ois = new ObjectInputStream(is);

            return ois.readObject();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}

建造器模式

让你给我们创建对象更加灵活,适用于一步一步构建一个较为复杂的对象

实现方法


public class Person {
    private String name;
    private String sex;
    private Integer weight;
    private Integer height;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", weight=" + weight +
                ", height=" + height +
                '}';
    }

    private Person(String name, String sex, Integer weight, Integer height) {
        this.name = name;
        this.sex = sex;
        this.weight = weight;
        this.height = height;
    }

    // 建造器
    public static class PersonBuilder{
        private String name;
        private String sex="男";
        private Integer weight=50;
        private Integer height;

        // 返回值类型不再是void 而是建造器类型本身
        public PersonBuilder name(String name) {
            this.name = name;
            return this;
        }
        public PersonBuilder sex(String sex) {
            this.sex = sex;
            return this;
        }
        public PersonBuilder weight(Integer weight) {
            this.weight = weight;
            return this;
        }
        public PersonBuilder height(Integer height) {
            this.height = height;
            return this;
        }
        public Person build() {
            // 需要的信息收集齐了
            return new Person(this.name,this.sex,this.weight,this.height);
        }
    }


    public String getName() {
        return name;
    }

    public String getSex() {
        return sex;
    }

    public Integer getWeight() {
        return weight;
    }

    public Integer getHeight() {
        return height;
    }
}

public class Test{
    public static void main(String[] args){
      Person person = new Person.PersonBulider()
      .sex("男");
      .name("张三");
      .height(170);
      .build();
      System.out.println(Person);
    }
}

迭代器模式(iterator)

当你实现的数据结构不一致时,迭代器以一种一致的方式进行集合的遍历,而不用在乎集合内的数据结构

实现方法

集合ArrayList、LinkedList、HashSet、TreeSet

都可以通过for(Object o : 集合)进行遍历
或者

    Iterator iter = 集合.iterator();
    while(iter.hasNext()){
        iter.next();
    }

策略模式

策略模式是对算法的包装,是把使用算法本身分割开来,委派给不同的对象管理。

实现方法

比如在Java中的集合或者数组排序算法(分为3种情况)

1.基本类型 双基点快速排序
2.引用类型 TimeSort(早期使用归并排序)
3.规模小 插入排序

排序的的算法是固定的,但是排序的规则不是固定的。我们可以通过比较器来实现不同的排序规则。
我们将不同的比较器接口的实现就称为排序策略(体现了open-close原则)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值