java设计模式入门(1)

java设计模式入门

java设计模式是为了增加代码的可复用性,可维护性,可扩展性,灵活性。
可复用性:可以重复使用
可维护性:要改动时只需要改需要改的地方
可扩展性:需要什么功能另外加上去就行了
灵活性:可以根据不同需求而使用

设计模式分为三种和六大原则
(1)创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

(2)结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

(3)行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

1、开闭原则:只能扩展新的,不能修改原有代码
2、里氏替换原则:子类的能力必须大于等于父类,即父类可以使用的方法,子类都可以使用 。
3、依赖倒转原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象
4、接口隔离原则:使用多个隔离的接口,而不使用单一的总接口,降低耦合
5、迪米特法则:个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。
6、合成复用原则:原则是尽量使用合成/聚合的方式,而不是使用继承

单例模式

单例模式是比较常见的一种设计模式,目的是保证一个类只能有一个实例,而且自行实例化并向整个系统提供这个实例,避免频繁创建对象,节约内存。

懒汉式

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

}

饿汉式

public class Singleton {
    private final static Singleton INSTANCE = new Singleton();
    
    private Singleton(){}    public static Singleton getInstance(){
        return INSTANCE;
    }}

双重校验锁

public class SingleTon3 {
         private SingleTon3(){};             //私有化构造方法
    
         private static volatile SingleTon3 singleTon=null;
    
         public static SingleTon3 getInstance(){
                  //第一次校验
                 if(singleTon==null){     
                synchronized(SingleTon3.class){
                           //第二次校验
                        if(singleTon==null){     
                         singleTon=new SingleTon3();
                         }
                }
     }
     return singleTon;
    }

为什么需要两次判断if(singleTon==null)?
  分析:第一次校验:由于单例模式只需要创建一次实例,如果后面再次调用getInstance方法时,则直接返回之前创建的实例,因此大部分时间不需要执行同步方法里面的代码,大大提高了性能。如果不加第一次校验的话,那跟上面的懒汉模式没什么区别,每次都要去竞争锁。
     第二次校验:如果没有第二次校验,假设线程t1执行了第一次校验后,判断为null,这时t2也获取了CPU执行权,也执行了第一次校验,判断也为null。接下来t2获得锁,创建实例。这时t1又获得CPU执行权,由于之前已经进行了第一次校验,结果为null(不会再次判断),获得锁后,直接创建实例。结果就会导致创建多个实例。所以需要在同步代码里面进行第二次校验,如果实例为空,则进行创建。
  需要注意的是,private static volatile SingleTon3 singleTon=null;需要加volatile关键字,否则会出现错误。问题的原因在于JVM指令重排优化的存在。在某个线程创建单例对象时,在构造方法被调用之前,就为该对象分配了内存空间并将对象的字段设置为默认值。此时就可以将分配的内存地址赋值给instance字段了,然而该对象可能还没有初始化。若紧接着另外一个线程来调用getInstance,取到的就是状态不正确的对象,程序就会出错。

模板方法模式

抽象父类定义需要实现单个方法和顶层逻辑(模板方法),子类实现父类的单个方法,创建父类的字类实例调用顶层逻辑实现模板方法。
例子:

public abstract class Game {
   abstract void initialize();
   abstract void startPlay();
   abstract void endPlay();
 
   //模板
   public final void play(){
 
      //初始化游戏
      initialize();
 
      //开始游戏
      startPlay();
 
      //结束游戏
      endPlay();
   }
}
public class Football extends Game {
 
   @Override
   void endPlay() {
      System.out.println("Football Game Finished!");
   }
 
   @Override
   void initialize() {
      System.out.println("Football Game Initialized! Start playing.");
   }
 
   @Override
   void startPlay() {
      System.out.println("Football Game Started. Enjoy the game!");
   }
}
public class TemplatePatternDemo {
   public static void main(String[] args) {
      Game game = new Football();
      game.play();      
   }
}

原型模式

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

当创建相同对象的时候,使用拷贝减少资源消耗达到高性能创建新的相同对象
其中要重新clone实现深拷贝(直接拷贝,序列化)

观察者模式

存在一对多的依赖关系时,使用观察者模式实现当Subject发生修改,Observer 通知到其他client。
即使用Observer观察者使Subject的消息可以通知到各个client,client到Obsever上注册/移除,当subject发生改变时,通知到observer,observer通知当前注册的所有client即为观察者模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值