单例模式主要是为了避免因为创建了多个实例造成资源的浪费,且多个实例由于多次调用容易导致结果出现错误,而使用单例模式能够保证整个应用中有且只有一个实例,即只提供一个取得其对象的方法
使用懒汉式,只有当程序需要new一个实例的时候,他才会去创建一个实例,
public class LazyMan {
private LazyMan() {
}
private static LazyMan lazyMan;
/**
* 线程不安全
* @return
*/
public static LazyMan getInstance() {
if (lazyMan==null){
lazyMan=new LazyMan();
}
return lazyMan;
}
/**
* 双重校验锁
* @return
*/
public static LazyMan getInstanceTwo(){
if(lazyMan==null){
synchronized (LazyMan.class){
if (lazyMan==null){
lazyMan=new LazyMan();
}
}
}
return lazyMan;
}
}
顾名思义,他是一个饿汉,他很勤快就怕自己饿着。他总是先把食物准备好,什么时候需要吃了,他随时拿来吃,不需要临时去搞食物。 即饿汉式在一开始类加载的时候就已经实例化,并且创建单例对象,以后只管用即可。 代码实现
/**
* 单例模式中的饿汉式
* 单例模式的饿汉式[可用]
* (1)私有化该类的构造函数
* (2)通过new在本类中创建一个本类对象
* (3)定义一个公有的方法,将在该类中所创建的对象返回
* <p>
* 优点:从它的实现中我们可以看到,这种方式的实现比较简单,在类加载的时候就完成了实例化,避免了线程的同步问题。
* 缺点:由于在类加载的时候就实例化了,所以没有达到Lazy Loading(懒加载)的效果,也就是说可能我没有用到这个实例,但是它
* 也会加载,会造成内存的浪费(但是这个浪费可以忽略,所以这种方式也是推荐使用的)。
*
* @Author sunjl
* @Date 2022/7/11 16:23
* @Version 1.0.0
*/
public class EvilMan {
private EvilMan() {
}
private static EvilMan evilMan = new EvilMan();
public static EvilMan getInstace() {
return evilMan;
}
/**
* 2. 单例模式的饿汉式变换写法[可用]
* 基本没区别
*/
private static EvilMan evilManTwo=null;
static {
evilMan=new EvilMan();
}
public static EvilMan getInstanceTwo(){
if (evilMan==null){
evilMan=new EvilMan();
}
return evilManTwo;
}
}
(1) 线程安全:饿汉式在线程还没出现之前就已经实例化了,所以饿汉式一定是线程安全的。懒汉式加载是在使用时才会去new 实例的,那么你去new的时候是一个动态的过程,是放到方法中实现的,比如:
public static synchronized Singleton getInstance(){
if(instance == null){
//什么时候用就什么时候new
instance = new Singleton();
}
}
java
如果这个时候有多个线程访问这个实例,这个时候实例还不存在,还在new,就会进入到方法中,有多少线程就会new出多少个实例。一个方法只能return一个实例,那最终return出哪个呢?是不是会覆盖很多new的实例?这种情况当然也可以解决,那就是加同步锁,避免这种情况发生 。
(2)执行效率:饿汉式没有加任何的锁,因此执行效率比较高。懒汉式一般使用都会加同步锁,效率比饿汉式差。 (3)内存使用:饿汉式在一开始类加载的时候就实例化,无论使用与否,都会实例化,所以会占据空间,浪费内存。懒汉式什么时候用就什么时候实例化,不浪费内存。
参考链接:https://blog.csdn.net/m0_60092917/article/details/118718889
项目中的辅助类,如HttpUtils.doGet()等,使用方式类+静态方法。
专门定义一个类来负责创建其他类的实例,将对象的创建和本身的业务逻辑分离,降低系统的耦合度,使得两个修改起来相对容易些,当以后实现改变时,只需要修改工厂类即可。(被创建的实例通常都具有共同的父类)
代码实现:
/**
* 简单工厂模式实现
*
* @Author sunjl
* @Date 2022/7/12 15:05
* @Version 1.0.0
*/
public class SimpleRoujiaMoFactory {
abstract class SJL {
}
public class SJL1 extends SJL {
public SJL1() {
System.out.println("创建实例1");
}
}
public class SJL2 extends SJL {
public SJL2() {
System.out.println("创建实例 2");
}
}
public class SJL3 extends SJL {
public SJL3() {
System.out.println("创建实例 3");
}
}
public SJL creatFactory(int type) {
SJL sjl = null;
switch (type) {
case 1:
sjl = new SJL1();
break;
case 2:
sjl = new SJL2();
break;
case 3:
sjl=new SJL3();
break;
}
return sjl;
}
}
java
使用工厂:
public static void main(String[] args) {
SimpleRoujiaMoFactory simpleRoujiaMoFactory = new SimpleRoujiaMoFactory();
simpleRoujiaMoFactory.creatFactory(2);
}
java
简单工厂模式提供专门的工厂类用于创建对象,实现了对象创建和使用的职责分离,客户端不需知道所创建的具体产品类的类名以及创建过程,只需知道具体产品类所对应的参数即可,通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。 但缺点在于不符合“开闭原则”,每次添加新产品就需要修改工厂类。在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展维护,并且工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。 为了解决简单工厂模式的问题,出现了工厂方法模式
参考链接:https://blog.csdn.net/a745233700/article/details/120253639
工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每 实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。
实现代码:
创建抽象工厂实现方法
/**
* 抽象创建工厂
* 注意,我们在这里采用了泛型(Generic),通过定义泛型对createHuman的输入参数产
* 生两层限制:
* ● 必须是Class类型;
* ● 必须是Human的实现类
*
* @Author sunjl
* @Date 2022/7/12 19:16
* @Version 1.0.0
*/
public abstract class AbstractHumanFactory {
public abstract <T extends Human> T creatHuman(Class<T> c);
}
java
实现方法
/**
* 创建工厂
*
* @Author sunjl
* @Date 2022/7/12 19:21
* @Version 1.0.0
*/
public class HumanFactory extends AbstractHumanFactory {
@Override
public <T extends Human> T creatHuman(Class<T> c) {
Human human = null;
//通过newInstance创建新的类的实例
try {
human = (T) Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T) human;
}
}
java
创建产品
/**
* 实现方法
*
* @Author sunjl
* @Date 2022/7/12 19:40
* @Version 1.0.0
*/
public class NvWa {
public static void main(String[] args) {
HumanFactory humanFactory = new HumanFactory();
BlackHuman blackHuman = humanFactory.creatHuman(BlackHuman.class);
blackHuman.getColor();
blackHuman.talk();
}
}
java
/**
* 实现逻辑方法
*
* @Author sunjl
* @Date 2022/7/12 19:04
* @Version 1.0.0
*/
public class BlackHuman implements Human {
@Override
public void getColor() {
System.out.println("一个黑人");
}
@Override
public void talk() {
System.out.println("黑人之话,");
}
}
java
/**
* 可理解为产品方法,逻辑方法判断
*
* @Author sunjl
* @Date 2022/7/12 19:02
* @Version 1.0.0
*/
public interface Human {
void getColor();
void talk();
}
java
当需要创建的产品具备复杂创建过程时,可以抽取出共性创建过程,然后交由具体实现类自定义创建流程,使得同样的创建行为可以生产出不同的产品,分离了创建与表示,使创建产品的灵活性大大增加。
主要用的地方是在实体类的链式编程中使用,
● Product产品类 通常是实现了模板方法模式,也就是有模板方法和基本方法,这个参考第10章的模板方 法模式。例子中的BenzModel和BMWModel就属于产品类。
● Builder抽象建造者 规范产品的组建,一般是由子类实现。例子中的CarBuilder就属于抽象建造者。
● ConcreteBuilder具体建造者 实现抽象类定义的所有方法,并且返回一个组建好的对象。例子中的BenzBuilder和 BMWBuilder就属于具体建造者。
● Director导演类 负责安排已有模块的顺序,然后告诉Builder开始建造,在上面的例子中就是我们的老 大,××公司找到老大,说我要这个或那个类型的车辆模型,然后老大就把命令传递给我,我 和我的团队就开始拼命地建造,于是一个项目建设完毕了。
代理模式(Proxy Pattern)是一个使用率非常高的模式,其定义如下: Provide a surrogate or placeholder for another object to control access to it.(为其他对象提供 一种代理以控制对这个对象的访问。)
● 职责清晰 真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理 完成一件事务,附带的结果就是编程简洁清晰。
● 高扩展性 具体主题角色是随时都会发生变化的,只要它实现了接口,甭管它如何变化,都逃不脱 如来佛的手掌(接口),那我们的代理类完全就可以在不做任何修改的情况下使用。
● 智能化 这在我们以上的讲解中还没有体现出来,不过在我们以下的动态代理章节中你就会看到 代理的智能化有兴趣的读者也可以看看Struts是如何把表单元素映射到对象上的
AOP框架时,弄清楚几个名词就成:切面(Aspect)、切入点 (JoinPoint)、通知(Advice)、织入(Weave)就足够了,理解了这几个名词,应用时你 就可以游刃有余了!
1.反射。用到了Class类中的静态方法forName(String className).传入的字符串参数是类的全路径名。因为可以传入字符串,所以这种方法也可以用到配置文件中,使其修改路径更加方便。
@SuppressWarnings("rawtypes")
Class cls = Class.forName("java.lang.String");
System.out.println(cls);
java
2.通过类的实例对象调用getClass()方法,这个方法是继承Object类得来的。
String str = "csdn";
Class cls2 = str.getClass();
System.out.println(cls2);
java
3.根据类名直接获取对应的Class的对象 : 类名.class
Class cls1 = String.class;
System.out.println(cls1);
java
加上this关键字,我就是要调用本类中的成员变量或方法,而不是本方 法中的一个变量。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有