设计模式

1 设计模式学习之旅

设计模式分为 创建型、结构型和行为型模式

1.1 工厂模式

工厂模式属于创建型模式,提供了一种创建对象的最佳方式。在工厂模式中,创建对象时不会对客户端暴露创建方式,通过一个共同的接口指向新创建的对象。
优点:创建对象时只需要知道对应的名称就可以;扩展性高,如果想增加一个产品,只需要增加工厂的扩展类即可;可以屏蔽具体的实现,只暴露接口即可

1.1.1 Spring中连接数据库使用工厂模式

连接数据库进行查询等操作的常规操作如下:注册驱动、连接数据库、操作的预处理对象、执行操作、释放资源

//1、注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver()); //如果把jdbc的MySQLjar包依赖去除直接编译失败提示没有mysql    
//2、获取连接
Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/","root","root");
//3、获取操作数据库的预处理对象
PreparedStatement pstm=conn.prepareStatement("select * from client");
//4、执行SQL,得到结果集
ResultSet rs=pstm.executeQuery();
//5、遍历结果集
while(rs.next()){
    System.out.println(rs.getString("name"));
}
//6、释放资源
rs.close();
pstm.close();
conn.close();

如何使用工厂模式简化这些操作,,,,,
使用Spring的时候我们知道,数据库的驱动地址、账号、密码都是配置在配置文件中的,如果想要切换数据库,只需要修改配置文件就可以
1、首先,驱动的获取,不能直接使用new的方式,new的方式就会强耦合,使用反射加载驱动
2、通过配置文件获取连接

1.2 单例模式

单例模式是最简单的设计模式,也是属于创建型模式,提供创建对象的最佳方式。这个模式涉及一个单一的类,该类负责创建自己的对象,且只保证只有一个对象被创建,这个类同时提供了一个访问这个对象的方式,可以直接访问,不需要再实例化。
原则:
单例类只能有一个实例;单例类需要自己生成这个单个实例;单例类创建的这个实例必须给其他对象提供
几种实现方式:
1)懒汉式(最基本的),线程不安全的,多线程情况下不能使用,因为没有锁,如果并发调用的时候,会产生因为对象还没有创建,导致多个同时创建;延迟初始化,实例不存在时才会初始化;

public class SingletonOne {
    private static SingletonOne singletonOne;
    private SingletonOne() {
    }
    public static SingletonOne getSingletonOne() {
        if(this.singletonOne == null) {
            return new SingletonOne();
        }
        return singletonOne;
    }
}

2)懒汉式(线程安全的),允许多线程,且实现了延迟加载,但是因为每次获取实例的方法时都要加锁,所以效率不高,一般情况下不建议使用这个方式

public class SingletonTwo {
    private static SingletonTwo singletonTwo = null;
    private SingletonTwo() {

    }
    public static synchronized SingletonTwo singletonTwo() {
        if (singletonTwo == null) {
            singletonTwo = new SingletonTwo();
        }
        return singletonTwo;
    }
}

3)饿汉式(线程安全的),但不是延迟加载的,饿汉–故名思义,,,单例类加载的时就会将对象初始化到内存中,正常来说单例类加载的原因是获取实例的时候,但是不排除其他因素,比如静态类加载,,,但是因为没有加锁,所以效率较高

public class SingletonThree {
    private static SingletonThree singletonThree = new SingletonThree();
    private SingletonThree() {

    }
    private static SingletonThree singletonThree() {
        return singletonThree;
    }
}

4)双重校验锁(线程安全的),就是获取实例时进行双重校验,获取实例的方法不加锁,只有判断实例不存在时再加锁获取实例,所以也是延迟加载型的,而且因为高并发的时候,并不是所有的都会锁住,所以效率较高

public class SingletonFour {
    private static SingletonFour singletonFour = null;
    private SingletonFour() {

    }
    public static SingletonFour singletonFour() {
        if (singletonFour == null) {
            synchronized (SingletonFour.class) {
                if (singletonFour == null) {
                    singletonFour = new SingletonFour();
                }
            }
        }
        return singletonFour;
    }
}

5)静态内部类(叫登记式,不知道为啥这样叫),在单例类中增加静态内部类,在静态内部类中实例化对象,因此只有去获取实例的时候才会加载,也实现了延迟加载,·而且类加载机制保证了只会有一个实例

public class SingletonFive {
    
    private SingletonFive() {

    }
    private static class SingletonFiveInner {
        private static SingletonFive singletonFive = new SingletonFive();
    }
    public static SingletonFive singletonFive() {
        return SingletonFiveInner.singletonFive;
    }
}

6)枚举方式

public enum  SingletonSix {
    SINGLETON_SIX
}

1.3 代理模式

一个类代表另一个类的功能(为其对象提供一个代理,以实现对这个对象的访问),这种模式称之为代理模式,这种设计模式是结构型模式。在代理模式中,我们创建具有现有对象的对象,以便向外界提供接口。
主要用来解决的问题:在直接访问某些对象时会带来的问题,,比如说创建对象需要很大的开销,在访问这个对象的时候需要做安全控制,直接访问会带来麻烦,那么我们就需要在访问这个对象之前加一个访问层,,,,我们最熟知的Spring AOP使用的就是代理。

Java中存在静态代理、JDK动态代理、CGLIB动态代理

1.3.1 静态代理

静态代理,就是在编译期间,代理类和被代理类之间的关系就确定了
基本实现方式为
1)首先是一个接口
2)被代理类实现这个接口,代理类也实现这个接口,但是代理类中肯定要创建一个被代理类的一个实例然后再调被代理类对应的方法,,,那么代理类在方法执行的前后就可以加入自己的想要实现的代码等信息
缺点:就是当接口中存在很多方法时,那么代理类就需要复写很多方法
接口

public interface TicketDao {
    public void sellTicket();
}

具体实现

public class TicketDaoImp implements TicketDao {
    @Override
    public void sellTicket() {
        System.out.println("买票,票减少了");
    }
}

代理实现

public class TicketProxy implements TicketDao {
    private TicketDaoImp ticketDaoImp = new TicketDaoImp();
    @Override
    public void sellTicket() {
        System.out.println("代售点售出");
        ticketDaoImp.sellTicket();
        System.out.println("买到了");
    }
}
1.3.2 JDK动态代理

代理实现

public class JdkTicketProxy implements InvocationHandler {
    private TicketDao ticketDao = null;


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("jdk动态代理");;
        Object object = null;
        object = method.invoke(ticketDao,args);
        System.out.println("Jdk代理买票成功");
        return object;
    }

    public JdkTicketProxy(TicketDao ticketDao) {
        this.ticketDao = ticketDao;
    }
}

未完待续…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值