Java设计模式之创建型模式

设计模式(创建型)

软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。

工厂方法模式(Factory Method Pattern)

  • 定义:它定义了一个用于创建对象的接口,但是让其子类决定将哪个类实例化。这使得一个类的实例化延迟到其子类。

public abstract class Fruit{    //水果抽象类
    private final String name;
    
    public Fruit(String name){
        this.name = name;
    }
    
    @Override
    public String toString(){
        return name + "@" + hashCode(); //打印一下当前水果名称,还有对象的hashCode
    }
}
  • 将对象的创建封装到工厂中

public abstract class FruitFactory<T extends Fruit>{    //将水果工厂抽象为抽象类,添加泛型T由子类指定水果类型
    public abstract T getFruit();   //不同的水果工厂,通过此方法生产不同的水果 
}
public class AppleFactory extends FruitFactory<Apple>{  //苹果工厂,直接返回Apple,一步到位
    @Override
    public Apple getFruit(){
        return new Apple();
    }
    
}
public class Apple extends Fruit{   //苹果,继承自水果
    
    public Apple(){
        super("苹果");
    }
}
public class Orange extends Fruit{  //橘子,也继承自水果
    public Orange(){
        super("橘子");
    }
}
public class Main{
    public static void main(String[] args){
        test(new AppleFactory::getFruit);   //比如现在要吃一个苹果,那么直接通过苹果工厂来获取苹果
    }
    
    //此方法模拟吃掉一个水果
    private static void test(Supplier<Fruit> supplier){
        System.out.println(suppiler.get() + "被吃掉了,真好吃!");
    }
}

抽象工厂模式(Abstract Factory Pattern)

  • 定义:它提供了一种将一组相关或相互依赖的对象创建的接口,而无需指定它们具体的类

public class Router{}
public class Table{}
public class Phone{}
public abtract class AbstractFactory{
    public abstract Phone getPhone();
    public abstract Table getTable();
    public abstract Router getRouter();
}

建造者模式(Builder Pattern)

  • 定义:它将对象的构建过程与其表示分离开来,使得同样的构建过程可以创建不同的表示

public class Student{
    //student的属性
    
    //一律使用建造者来创建,不对外直接开放
    private Student(int id,int age,int grade,String name,String college,String profession,List<String> awards){
        //初始化属性
    }
    
    public static StudentBuilder builder(){	//通过builder方法直接获取建造者
        return new StudentBuilder();
    }
    
    public static class StudentBuilder{	//这里就直接创建一个内部类
        //Builder也需要将所有的参数都进行暂时保存,所有Student怎么定义的这里就怎么定义
        int id;
        int age;
        int grade;
        String name;
        String college;
        String profession;
        List<String> awards;
        
        
        public StudentBuilder id(int id){	//直接调用建造者对应的方法,为对应的属性赋值
            this.id = id;
            return this;	//为了支持链式调用,这里直接返回建造者本身,下同
        }
        
         public StudentBuilder age(int age){
            this.age = age;
            return this;	
        }
        
        ...
            
         public StudentBuilder awards(String... awards){	
            this.awards = Arrays.asList(awards);
            return this;
        }
        
        public Student build(){	//最后只需要调用建造者提供的build方法即可根据配置返回一个对象
            return new Student(id,age,grade,name,college,profession,awards);
        }
    }
}
  • 使用建造者来生成对象:

public static void main(String[] args){
    Student student = student.builder()	//获取建造者
    		.id(1)	//逐步配置各个参数
        	.age(18)
        	.grade(3)
        	.name("小明")
        	.awards("ICPC-ACM 区域赛 金牌","LPL 2022春季赛 冠军")
        	.build();	//最后直接建造想要的对象
    	
}

单例模式(Singleton Pattern)

  • 定义:它确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。

  • 使用场景:线程池和数据库链接的时候会使用到单例模式

  • 饿汉式和懒汉式的相同点和不同点

    • 相同点:

      • 私有的构造函数

      • 对外曝光一个方法进行提供对应的实例

    • 不同点:

      • 饿汉式:在属性上进行实例化对象,于是在类上,类构建的时候就会进行实例化

      • 懒汉式:在使用的时候进行实例化当前的对象

  • 饿汉式

public class Singleton{
    //必须进行创建这个实例
    private final static Singleton SINGLETON = new Singleton();
    
    //必须要有的私有的构造函数。防止直接new对象
    private Singleton(){}
    
    //向对外提供一个实例,如需要使用该实例对象,则是必须要通过此方法
    public static Singleton getSingleton(){
        return SINGLETON;
    }
}
public class MainTest{
    public static void main(String[] args){
        Singleton s = Singleton.getSingleton();
        Singleton s1 = Singleton.getSingleton();
        System.out.println(s == s1);	//true
    }
}

  • 懒汉式(线程安全)

public class Singleton{
    //必须进行创建这个实例,volatile保证instance在线程之间的可见性
    private volatile static Singleton instance;
    
    //必须要有的私有的构造函数。防止直接new对象
    private Singleton(){}
    
    //向对外提供一个实例,如需要使用该实例对象,则是必须要通过此方法
    //lock锁
    public static Singleton getSingleton(){
        
        //进行创建对象
        if(instance == null){
            //双重检查锁定
            synchronized(Singleton.class){
                if(instance == null){
                     Singleton singleton = new Singleton();
            		 instance = singleton;
                }
            }
        }
        return instance;
    }
}

原型模式(Prototype Pattern)

  • 定义:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象

  • 浅拷贝:对于类中基本数据类型,会直接赋值值给拷贝对象;对于引用类型,只会对复制对象的地址,而实际上指向的还是原来的那个对象

    public static void main(String[] args){
        int a = 10;
        int b = a;	//基本类型浅拷贝
        System.out.println(a == b);
        
        Object o = new Object();
        Object k = o;	//引用类型浅拷贝,拷贝的仅仅是对象上面对象的引用
        System.out.println(o == k);
    }
  • 深拷贝:无论是基本类型还是引用类型,深拷贝会将引用类型的所有内容,全部拷贝为一个新的对象,包括对象内部的所有成员变量,也会进行拷贝

public class Student implements Cloneable{
    String name;
    
    public Student(String name){
        this.name = name;
    }
    
    public String getName(){
        return name;
    }
    
    @Override
    public Object clone() throws CloneNotSupportedException{	//改进一下,针对成员变量也进行拷贝
        Student student = (Student) super.clone();
        student.name = new String(name);
        return student;	//拷贝完成后,再返回
    }
}
public static void main(String[] args) throws CloneNotSupportedException{
    Student student = new Student("小明");
    Student student1 = (Student)student.clone();
    System.out.println(student.getName() == student1.getName());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼粮爱编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值