一 GrilFriendClass 引言
N 先生很快就要大学毕业, 大学四年忙于学 (网) 业(游), 也没有找个女朋友每每回家, 家人都催促他赶快谈一个, 或者干脆说要直接给 N 先生介绍对象
有句话说什么样的年龄就该做什么样的事情, 这句话放在当下还是很有道理的可是 N 先生心中对成家立业是有自己的认识的, 认为先立业而后成家, 自己都没条件过平凡的日子怎么给另一半想要的生活呢
但是由于家里催的紧, N 先生就想到了租女友先应付家里的姑姑阿姨们
---
于是这一年每逢过节回家, N 先生都会带新对象回家,
这年端午节, N 先生租安琪拉回家了, 家里人都夸着说 N 的对象看着很乖巧,
我们都知道这里 N 的对象就是指的安琪拉
同年中秋节, N 先生租孙尚香回家了, 家里人都夸着说 N 的对象像个大小姐
我们都知道这里 N 的对象就是指的孙尚香
又到国庆节, N 先生租蔡文姬回家了, 家里人都夸着说 N 的对象十分卡哇伊
我们都知道这里 N 的对象就是指的蔡文姬
---
这一年来, 家人没见到 N 先生时都会夸 N 的对象, 但每次夸的对象都不一样, 这里不是同一个对象
当全局系统每需要调用某个类 N 时, 需要创建一个类 N 的新对象, 即便创建的对象名称相同, 也不是同一个对象
终于, 毕业后的 N 先生在合适的年龄遇到了真爱不知火舞, 确定了自己唯一的对象, 这几趟回家, 家里人提及 N 先生的对象时, 都赞不绝口说大学生活不错
我们都知道, 毕业后大家提到的 N 的对象都是不知火舞这里是同一个对象
在软件工程单例模式思想出来之前, 每当开发者使用某个类时都会新建一个对象实例使用, 优秀的开发者会在使用结束后释放掉对象占用的资源, 单一般开发过程中很少在意这一点于是这些没被释放资源的对象就成为了 Java 虚拟机里的垃圾单例模式就是保证了系统全局只存在唯一的一个实例对象确定了唯一对象的 N 先生, 也代表了毕业前后 N 先生更加的成熟
二 GrilFriendSingleton 实例演示
2-1 GrilFriendUnSingleton 非单例模式实例
在单例模式之前, 我们会这样写一个 Class , 写基本属性和类的相关方法, 及构造函数或者带参数的构造函数下面以默认构造方法为例代码演示
- package pers.niaonao.entity;
- /**
- * @author niaonao
- * 非单例模式下的基本类
- */
- public class GrilFriendUnSingleton {
- // 默认的构造方法
- public GrilFriendUnSingleton() {
- }
- private String info = "我是你的新 GrilFriend";
- /**
- * 获取对象信息的方法
- * @return
- */
- public String getGrilFriend() {
- return info;
- }
- }
通过新建该类的实体对象来调用相关方法
- package pers.niaonao.test;
- import pers.niaonao.entity.GrilFriendUnSingleton;
- /**
- * @author niaonao
- *
- */
- public class TestGrilFriend {
- public static void main(String[] args) {
- // 对实体类创建两个对象
- GrilFriendUnSingleton n_first_grilfriend = new GrilFriendUnSingleton();
- GrilFriendUnSingleton n_next_grilfriend = new GrilFriendUnSingleton();
- String info = "n_first_grilfriend 和 n_next_grilfriend";
- // 判断对象是否是同一个实例
- if (n_first_grilfriend != n_next_grilfriend) {
- info += "\n\t 不是同一个实例, 是两个不同的对象:"
- + "\n\t 魔法为我而存在," + n_first_grilfriend.getGrilFriend()
- + "\n\t 大小姐驾到," + n_next_grilfriend.getGrilFriend();
- } else {
- info += "\n\t 是同一个实例, 同一个对象:"
- + "\n\t 会用不知火流的烈焰烧死你的呦," + n_first_grilfriend.getGrilFriend()
- + "\n\t 会用不知火流的烈焰烧死你的呦," + n_next_grilfriend.getGrilFriend();
- }
- System.out.println(info);
- }
- }
程序执行结果如下:
我们在系统全局每需要使用该类时, 都会在使用该类的地方通过构造方法新建类的实体对象所以就会出现在系统全局内, 存在多个当前类的对象, 并且其他地方就使用一次就不使用了, 新建了一个对象占用了一定的资源, 但没有释放资源, 这就造成资源的浪费, 也是系统垃圾的一种
2-2 GrilFriendBySingleton 单例模式实例
使用单例模式去写一个 class
- package pers.niaonao.test;
- import pers.niaonao.entity.GrilFriendBySingleton;
- /**
- * @author niaonao
- *
- */
- public class TestGrilFriend {
- public static void main(String[] args) {
- // 通过单例模式创建出两个实体常量
- GrilFriendBySingleton n_first_grilfriend = GrilFriendBySingleton.getInstance();
- GrilFriendBySingleton n_next_grilfriend = GrilFriendBySingleton.getInstance();
- String info = "n_first_grilfriend 和 n_next_grilfriend";
- // 判断对象是否是同一个实例
- if (n_first_grilfriend != n_next_grilfriend) {
- info += "\n\t 不是同一个实例, 是两个不同的对象:"
- + "\n\t 魔法为我而存在," + n_first_grilfriend.getGrilFriend()
- + "\n\t 大小姐驾到," + n_next_grilfriend.getGrilFriend();
- } else {
- info += "\n\t 是同一个实例, 同一个对象:"
- + "\n\t 会用不知火流的烈焰烧死你的呦," + n_first_grilfriend.getGrilFriend()
- + "\n\t 会用不知火流的烈焰烧死你的呦," + n_next_grilfriend.getGrilFriend();
- }
- System.out.println(info);
- }
- }
测试类 TestGrilFriend 来测试单例模式
- package pers.niaonao.test;
- import pers.niaonao.entity.GrilFriendBySingleton;
- /**
- * @author niaonao
- *
- */
- public class TestGrilFriend {
- public static void main(String[] args) {
- // 通过单例模式创建出两个实体常量
- GrilFriendBySingleton n_first_grilfriend = GrilFriendBySingleton.getInstance();
- GrilFriendBySingleton n_next_grilfriend = GrilFriendBySingleton.getInstance();
- String info = "n_first_grilfriend 和 n_next_grilfriend";
- // 判断对象是否是同一个实例
- if (n_first_grilfriend != n_next_grilfriend) {
- info += "\n\t 不是同一个实例, 是两个不同的对象:"
- + "\n\t 魔法为我而存在," + n_first_grilfriend.getGrilFriend()
- + "\n\t 大小姐驾到," + n_next_grilfriend.getGrilFriend();
- } else {
- info += "\n\t 是同一个实例, 同一个对象:"
- + "\n\t 会用不知火流的烈焰烧死你的呦," + n_first_grilfriend.getGrilFriend()
- + "\n\t 会用不知火流的烈焰烧死你的呦," + n_next_grilfriend.getGrilFriend();
- }
- System.out.println(info);
- }
- }
程序执行结果如下:
即使对 GrilFriendBySingleton 创建了两个变量, 但通过单例模式保证是同一个实例, 即在内存中是存放在一个位置的一个对象保证了系统全局内只存在唯一的一个实例这就是单例模式
三 Singleton Pattern 单例模式
通过前两部分, 应该对单例模式有一定的理解及认识, 并能运用单例在实际开发中下面说一下单例模式的定义, 意义
3-1 定义
Ensure a class only has one instance,and provide a global point of access to it.
GOF 对单例模式的定义是, 保证一个类只有一个实例存在, 同时提供能对该实例加以访问的全局访问方法
3-2 类图
3-3 三要素
必须保证一个类只能有一个实例
必须是这个类自行创建这个实例
必须自行向整个系统提供这实例
3-4. 优缺点
使用单例模式必然要了解其优缺点
优点
客户端使用单例模式类的实例, 只需要调用一个单一的方法即可生成唯一的实例, 节约了资源
缺点
单例模式难以实现序列化 Serialization, 所以采用单例模式的类很难被持久化, 也不易通过网络传输, 一般网络传输数据都会序列化对象相关的类
单例模式采用静态方法 static, 不支持面向对象的三大特性之一的继承, 无法再继承结构 extend 中使用
如果分布式集群的环境下存在多个 Java 虚拟机, 不易确定具体的哪个单例在运行
3-5 应用场景
一般会在 Util 工具类中 service 服务类中使用, 部分 entity 类中
在多线程之间, 公用同一个资源或操作同一个对象, 这时候就用单例模式; 在系统全局都会使用到的, 共享资源, 全局变量, 可以使用单例模式; 之所以说部分 entity 实体类会使用单例模式, 是因为在大规模系统中, 考虑到性能节约对象的创建时间, 会使用单例模式
3-6 说明
上面的 GrilFriendBySingleton 实现中, 我们通过 getInstance() 保证只有一个实例存在, 通过关键字 static 修饰 getInstance() 方法, 提供全局访问的方法
我们得通过 GrilFriendBySingleton 提供的方法去获取单例, 让类自己创建实例, 不能通过构造方法 new GrilFriendBySingleton()再去创建, 这就违背了单例模式的创建初衷
3-7 标准单例代码演示
最后标准单例模式代码演示:
- public class Singleton {
- private static Singleton uniqueInstance = null;
- private Singleton() {
- // Exists only to defeat instantiation.
- }
- public static Singleton getInstance() {
- if (uniqueInstance == null) {
- uniqueInstance = new Singleton();
- }
- return uniqueInstance;
- }
- // Other methods...
- }
- END
来源: http://blog.csdn.net/niaonao/article/details/79500198