Java 几种设计模式
一.单例模式:
单个实例(某个类只能创建一个对象):
懒汉式:在第一次获取的时候创建对象,线程不安全 ,相对效率较高
饿汉式:类第一次加载以后就创建对象,线程安全的,相对效率较低
实现步骤:
1.构造器私有化(为了不让在外部直接new对象,而是通过调用类的静态方法取该类的对象)
2.提供一个静态的私有的该类的引用(静态是因为可在静态方法中直接使用,而无需用对象调用,私有是为了不让其在外被获取或使用)
3.提供一个公共的静态的访问方式->给你对象
懒汉式:
在第一次获取对象的时候创建对象,线程不安全,相对效率较高(多线程下)
public class SingleDemo {
//1.构造器私有化,使得在外部无法new一个对象
private SingleDemo(){
}
//2.提供一个私有的静态的该类的引用 用来存储未来创建的当前的实例
private static SingleDemo singleTon=null;
//3.提供一个公共的静态的访问方式->给你对象
/*public static SingleDemo newInstance(){
if(singleTon==null){
singleTon=new SingleDemo();
}
return singleTon;
}*/
//多线程环境控制单例安全,可以手动控制线程安全问题,在方法上加锁(同步锁synchronized)
public static synchronized SingleDemo newInstance(){
if(singleTon==null){
singleTon=new SingleDemo();
}
return singleTon;
}
}
饿汉式:
类第一次加载时就创建对象,线程安全,但相对效率较低
public class Single {
//1.构造器私有
private Single(){
}
//2私有的静态的该类的引用,静态成员,类加载便执行,就创建一个对象
private static Single single=new Single();
//3.公共的静态的访问方式
public static Single newInstance(){
return single;
}
}
测试:
public class Test {
public static void main(String[] args) {
//静态方法,通过类名.调用
System.out.println(SingleDemo.newInstance());
System.out.println(Single.newInstance());
}
}
二.简单工厂模式:
简单工厂模式:
抽象产品角色: 是具体产品角色继承的父类|实现的父接口
具体产品角色
工厂
public class FactoryDemo {
public static void main(String[] args) {
//接口多态
Car car=factory("Me");
car.run();
}
//工厂
//工厂造车返回车 所以返回值为Car引用类型
//想要工厂造什么车 所以传入车名这个方法参数
public static Car factory(String name){
//先定义一个Car引用类型
Car car=null;
//通过方法参数判断是什么车,将不同的车作为返回值返回
if("Ms".equals(name)){
//若车名时Ms,则将new Ms()这个对象赋值给car(多态)
car=new Ms();
}else{
car=new Me();
}
//返回Car类型的car
return car;
}
}
//抽象产品角色,Car接口
interface Car{
void run();
}
//具体产品角色,实现Car接口,重写方法,才可在工厂里实现接口的多态
class Ms implements Car{
@Override
public void run() {
System.out.println("一辆红色的玛莎拉蒂跑...");
}
}
//具体产品角色,不同的车 都是Car这个父接口
class Me implements Car{
@Override
public void run() {
System.out.println("一辆奔驰在跑..");
}
}
三.代理模式:
代理模式:
动态代理:结合反射
静态代理:
代理对象角色内部含有对真实对象的引用,从而可以操作真是对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能够代替真实对象。同时,代理对象可以在执行真实对象的操作时,附加其他操作,相当于对真是对象进行封装。
真实角色:拿角色的
代理角色:帮助真实角色做事情的
1.真实角色和代理角色实现相同的接口|父类(想要实现的功能)
2.代理角色必须持有真实觉得的引用
3.代理行为
在代理之前存在真实角色,其内容是真实角色的需求
优点:使用代理,减少了与真实角色的沟通,解耦,便于后期修改与维护
public class StaticProxy {
public static void main(String[] args) {
Manager manager=new Manager("林老师");//new真实角色对象
Hr hr=new Hr("卢妹妹",manager);//将真实角色对象传入代理角色,实现代理
hr.addUser();
}
}
//相同的接口,想要实现的功能:录用人
interface AddUser{
void addUser();
}
//真实角色 项目经理
class Manager implements AddUser{
String name;
//带参构造
public Manager(String name) {
this.name=name;
}
//重写接口抽象方法
@Override
public void addUser() {
System.out.println("....录用了");
}
}
//代理角色 Hr
class Hr implements AddUser{
String name;
//持有真实角色的引用,才能体现出这个类是上一个类的代理角色
//将Manager引用类型的变量作为代理角色的成员变量(持有真实角色的引用)
Manager manager= null;
//带参构造
public Hr(String name,Manager manager) {
this.name=name;
this.manager=manager;
}
@Override
public void addUser() {
System.out.println("发布招聘信息..");
manager.addUser();
System.out.println("谈薪资录用...");
}
}