作者:MarinaTsang
来源:CSDN
原文:https://blog.csdn.net/MarinaTsang/article/details/84141785
版权声明:转载链接!
单例设计模式
概念:
全局只有一个实例,自行实例化对象,自行向整个系统提供这个实例。
应用场景:
需要全局只有一个实例的时候,如保存用户信息。
只有一个访问途径
优点:
全局只有一个实例,避免了频繁的创建实例,耗费的资源。
提供了对唯一实例的受控访问。
允许改变数目的实例。
缺点:
单例模式没有抽象层,因此单例类扩展困难。
单例职责过重。
滥用单例可能造成其他问题,例如:持有上下文无法释放造成内存泄漏;实例化的对象长期未被使用,被回收导致对象状态丢失。
单例实现的几种方式
饿汉式
类加载的时候就开始加载,使用的是静态变量,由JVM的classloader机制避免了线程安全问题,保证线程安全。
缺点:一开始便加载占用内存,没有达到懒加载效果,如果实例化是耗费资源的,则懒加载可以节省加载时耗费的资源。另外如果实例一直没有使用会占用内存。
public class SingleTon{
private static SingleTon single = new SingleTon();
private SingleTon(){}
public static SingleTon getInstanceO(){
retrun single;
}
}
1
2
3
4
5
6
7
8
9
饿汉式的另外方式
与正常的饿汉式并没有太大的区别。
public class SingleTon{
private SingleTon instance = null;
static{
instance = new SingleTon();
}
private SingleTon(){}
public static SingleTon getInstance(){
return this.instance;
}
}
1
2
3
4
5
6
7
8
9
10
懒汉式
延迟加载,在调用getInstance的时候才开始加载,无须一直占用系统资源。从资源利用率的角度来讲优于饿汉式。
缺点:线程不安全,当线程A判断了是空的时候进行创建对象,在创建对象前线程B进来判断到是空,也创建了对象,因此线程A和线程B的对象不一致。
public class SingleTon {
private static SingleTon single;
private SingleTon(){}
public static SingleTon getInstance(){
if(single == null){
single = new SingleTon();
}
return single;
}
}
//优化---增加锁机制 1 ,在方法上加
public synchronize SingleTon getInstance(){
if(single == null){
single = new SingleTon();
}
}
//缺点:锁住了整个类,这个类中的其他成员变量也需要等待释放锁后被其他线程使用,效率低下。
//优化,双重锁校验,缺点:可能会出现等待时间,降低系统性能。
public static SingleTon getInstance(){
if(single == null){
synchronize(SingleTon.class){
if(single == null){
single = new SingleTon();
}
}
}
return single;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
静态内部类
静态内部类不是在一开始启动的时候加载,而是第一次调用的使用加载,实现了懒加载,并且由JVM的classloader机制实现线程同步,保证线程安全。
虚拟机会保证一个类的构造器()方法在多线程环境中被正确地加载,同步,如果多个线程同时去初始化一个类,那么只有一个线程去执行这个类的.
public class SingleTon{
private SingleTon();
private static class SingleTonHelper{
private static final SingleTon single = new SingleTon();
}
public static SingleTon getInstance(){
retrun SingleTonHelper.single;
}
}
1
2
3
4
5
6
7
8
9
10
11
观察者模式
概念:
实现一对多的依赖关系,当一方改变时,存在依赖关系的多方可以做出更改。
即发布订阅关系,发布者发布消息,存在订阅关系的订阅者可以接收消息。
包含的类
抽象被观察者接口:定义被观察者需要实现的接口,如注册观察者建立关系;移除观察者,通知所有观察变化。
抽象观察者接口:定义接收到消息后的更新方法。
具体被观察者:抽象被观察者实现者,与观察者建立关系,并通知观察者的实现方法。
具体观察者:被通知对象,具体实现收到通知后做出更新。
定义被观察者接口
public Interface IObservable{
void registObserver(IObserver o);
void removeObserver(IObserver o);
void notifyObserver();
}
1
2
3
4
5
定义观察者接口
public Interface IObserver{
void update(Strign message); //传入的参数时任意想接收的消息
}
1
2
3
具体被观察者实现
public class MyObservable impelement IObservable{
private String message ;//需要传递的消息
private List<IObserver> observers ;
public MyObservable(){
observers = new ArrayList<>();
}
@override
public void registObserver(IObserver o){
if(observers!=null){
observers.add(o);
}
}
@override
public void removeObserver(IObserver o){
if(observers!=null && observers.size()>0){
observers.remove(o);
}
}
@override
public void notifyObserver(){
for(int i=0 ;i<observers.size();i++){
observers.get(i).update(message);
}
}
//需要更新的消息
public void sendMsg(String msg){
this.message = msg;
//通知观察者
notifyObserver();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
具体观察者
public class MyObserver impelement IObserver{
@override
public void update(String message){
System.out.println("接收到消息,开始处理");
}
}
1
2
3
4
5
6
工厂模式
概念:
集中创建产品的类,是调用者和具体创建实例类分离开来,实现解偶。
简单工厂模式
概念与步骤
又叫静态工厂模式,通过工厂类根据类型创建不同的实例类。
优点:结构简单,便于理解。客户不用关心具体的类的创建过程。
缺点:代码逻辑较其他工厂模式复杂,新增产品时必须修改工厂类。当需要创建的类比较多时,工厂类会变的较为臃肿。
//需创建的实例类的共同点
public interface Car{
void go();
}
//具体实例
public class Audi{
@override
public void go(){
System.out.println("奥迪在跑");
}
}
public class Baoma{
@override
public void go(){
System.out.println("奥迪在跑");
}
}
//工厂类
public class CarFactory{
public static final int AUDI_TYPR = 1;
public static final int BMW_TYPR = 2;
public static Car createCar(int type){
Car car = null;
switch(type){
case AUDI_TYPR:
car = new Audi();
case BMW_TYPR:
car = new Baoma();
}
return car;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
工厂方法模式
概念与步骤
把工厂类抽象出去,创建实例由具体的工厂类实现,针对每一个产品都由自己的具体工厂类实现。
优点:
调用者无需关心产品的实现,只需要关心产品的接口。增加新的产品时,只要接口不变,不需要修改工厂类的逻辑,实现解偶。
缺点:
类比较多,如果需要创建多个产品的时候项目结构会比较大。
//抽象工厂接口
public interface IFactory{
Car createCar();
}
//具体工厂类
public class AudiFactory impelement IFactory{
@Override
public Car createCar(){
return new Audi();
}
}
//抽象产品
public interface Car{
void getName();
}
//具体的产品
public class Audi impelement Car{
@Override
public void getName(){
System.out.println("get an audi");
}
}
//新增产品时新增产品类及产品工厂类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
抽象工厂模式
概念与步骤
具有关联功能的产品作为一个产品族。 步骤:抽象工厂类,定于具体工厂类必须要实现的方法。
具体工厂类,创建一族产品;抽象产品类:定义产品的共性。具体产品类:创建具体的产品。
优点:具有工厂方法模式的优点外,另外可以在类内对产品族进行约束。
缺点:扩展比较麻烦。
试用场景:当创建的对象是一系列相互关联或相互依赖的产品族时适用。
//抽象工厂类
public interface AbstractFactory {
AbstractCar createCar();
AbstractPlane createPlane();
}
//抽象产品类
public abstract class AbstractCar {
public abstract void getName();
}
public abstract class AbstractPlane {
public abstract void getName();
}
//具体工厂类
public class BigFactory implements AbstractFactory{
@Override
public AbstractCar createCar() {
return new BigCar();
}
@Override
public AbstractPlane createPlane() {
return new BigPlane();
}
}
//具体产品类
public class BigCar extends AbstractCar {
@Override
public void getName() {
System.out.print("抽象工厂-大车");
}
}
class BigPlane extends AbstractPlane {
@Override
public void getName() {
System.out.print("抽象工厂-大飞机");
}
}
---------------------
作者:MarinaTsang
来源:CSDN
原文:https://blog.csdn.net/MarinaTsang/article/details/84141785
版权声明:转载链接!