当前位置:首页 > 服务端 > Java之常用设计模式(精简)

Java之常用设计模式(精简)

2022年09月16日 14:33:53服务端4

话不多说奔主题,精神抖擞就是干!

 

Java中共包含23种设计模式,大致分为三种类型:
1. 创建型模式:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。

2. 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。

3. 行为型模式:模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式。

 

下面介绍常用的几种:

1. 单例模式:是个程序一般都会用到这个模式。比如日志类,整个项目工程可能只需要创建一次,重复创建也只是返回第一次创建的实例的引用。

//饿汉模式

public class HungrySingleTon implement Serializable{

  // 保证序列化和反序列化时的对象的兼容性

  static  final long serialVersion = 42L;

  //快加载,利用了JVM类的懒加载机制保证线程安全

  private static final HungrySingleTon singleTon = new HungrySingleTon();

  private HungrySingleTon()

  {

    //防止利用反射来生成实例,破坏单例机制

    if (singleTon != null) {

      throw new RunTimeException("单例禁止反射");

    }

  };

  public static HungrySingleTon GetInstance() { return singleTon; }

}

//静态内部类,利用了JVM类的懒加载机制保证线程安全

public class SingleTon {

  private static class InnerSingleTon {

    private static SingleTon singleTon = new SingleTon();

  }

  private SingleTon() {

    //防止利用反射来生成实例,破坏单例机制

    if (singleTon != null) {

      throw new RunTimeException("单例禁止反射");

    }

  };

  public static SingleTon  GetInstance() { return InnerSingleTon.singleTon; }

}

//懒汉模式

public class LazySingleTon {

  //利用 volatile 禁止指令重排,保证线程之间可见性和一致性

  private static volatile LazySingleTon singleTon = null;

  private LazySingleTon() {};

  //懒加载,利用 synchronized 保证线程间的原子性

  public static LazySingleTon GetInstance() {

    if (null == singleTon) {

      synchronized (LazySingleTon.class) {

        if (null == singleTon) {

          singleTon = new LazySingleTon();

        }

      }

    }

    return singleTon;

   }

}

*要点:构造函数私有化,new前双次判空加锁。

 

2. 工厂模式:集中化生产同一类产品(存在差异化),比如造车厂,我可能只造小轿车,但是小轿车可能有不同的颜色搭配,还有经济型、标准型、豪华型等性能搭配。

2.1 简单工厂

public class Car {

  public Color color;  //颜色

  public Car (Color color) { this.color = color; }

}

public class PianYiCar extends Car {

  public PianYICar(Color color) { super.color = color; }

}

public class XiaoZiCar  extends Car {

  public XiaoZiCar  (Color color) { super.color = color; }

}

public class GuiCar  extends Car {

  public GuiCar  (Color color) { super.color = color; }

}

public class CarFactory {

  public Car Create(Type type, Color color) {

    switch(type) {

      case '经济型': return new PianYiCar (color);

      case '标准型': return new XiaoZiCar  (color);

      case '豪华型': return new GuiCar(color);

      default: return new Car(color);

    }

  }

}

*要点:简单工厂,其实就是条件工厂,根据不同条件去创建同一类型的差异化对象。

 

2.2 工厂方法:定义一个工厂类该类定义了一些标准方法但没有具体实现,通过不同的子类继承这个工厂父类并实现其标准方法去创造相同(存在差异化)或不同类型的对象。

//开闭原则

public  abstract class CarFactory {

  public abstract Car CreateCar(Color color);

}

//单一职责原则

public class PianYiCarFactory {

  @Override

  public Car CreateCar(Color color) {new PianYiCar(color); }

}

public class XiaoZiCarFactory {

  @Override

  public Car CreateCar(Color color) {new XiaoZiCar(color); }

}

public class GuiCarFactory {

  @Override

  public Car CreateCar(Color color) {new GuiCar(color); }

}

*要点:具体实施的工作不再由父工厂去完成,父工厂定义了行业标准,而子工厂根据老大说的标准,各自去完成自己的事情。

 

2.3 抽象工厂模式:由方法工厂组合演变而来

public interface IConn {

  public IConn getConn();

}

public interface IComm {

  public IComm getComm();

}

public interface IDataBaseUtils {

  public IConn getConn();

  public IComm getComm();

}

public class MySqlDataBase implement IDataBaseUtils {

  public IConn getConn() {

    system.out.println("mysql connected");

  }

  public IComm getComm() {

    system.out.println("mysql command");

  }

}

public class OracleDataBase implement IDataBaseUtils {

  public IConn getConn() {

    system.out.println("oracle connected");

  }

  public IComm getComm() {

    system.out.println("oracle command");

  }

}

 

3. 建造者模式

//使用场景:对象具有复杂结构,内部具有依赖关系顺序

public class Product {

  private final string proName;

  private final string part1;

  private final string part2;

  public Product(string proName, string part1, string part2) {

    this.proName = proName;

    this.part1 = part1;

    this.part2 = part2;

  }

  public class Builder { 

    private string proName;

    private string part1;

    private string part2;

    public Builder proName(string proName) { this.proName = proName; return this; }

    public Builder part1(string part1) { this.part1 = part1; return this; }

    public Builder part2(string part2) { this.part2 = part2; return this; }

  }

  public Product build () { return new Product(this.proName, this.part1, this.part2); }

}

调用

Product product = new Product.Builder().proName("Car").part1("1").part2("2").build();

*要点:建造者独立,便于扩展,内部细节可控。

 

4. 适配器模式

4.1 类适配器

先讲个小故事。大家在日常生活里,有没有遇到过这种情况,我的手机快没电了想要充电,但是手头只有一个二插头的充电器和一个三插头的插线板,woc,怎么办?好急啊!在线等~

那这种情况下我们是不是可以采取一些极端手段,比如把二插头的充电器的两只腿掰弯,这样是不是就能插进三插头的插线板里充电了呢?哈哈哈,没错,我真是个天才!

public Interface TwoChong {

  public void  TwoChongDian();

}

public Interface ThreeChong {

  public void  ThreeChongDian();

}

public class TwoChongImpl implements TwoChong {

  @Override

  public void TwoChongDian() { System.out.println("充电"); }

}

//下面这个就是你掰弯后的二插头充电器了^-^

public class TwoChongImplEx extends TwoChongImpl implements ThreeChong {

  @Override

  public void ThreeChongDian() { super.TwoChongDain(); }

}

*要点:其实说白了,就是对现有功能的一种扩展。

 

4.2 对象适配器:它是对类适配器的一种衍生,因为类适配具有强绑定、强约束性,调用污染,不方便扩展。

public class ThreeChongImpl implements ThreeChong {

  private TwoChongImpl twoChongImpl = null;

  public ThreeChongImpl(TwoChongImpl twoChongImpl) { this.twoChongImpl = twoChongImpl; }

  @Override

  public  void ThreeChongDian() { twoChongImpl.TwoChongDian(); }

}

 

4.3 接口适配器:减少代码量,提高可读性。

 public interface A {

  public void Do();

}

public class AA implements A {

  @Override

  public void Do() {}

}

public class AAA extends AA {

  @Override

  public void Do() { System.out.println("实际工作"); }

}

 

5. 装饰者模式:扩展功能可以组合叠加,互相直接没有干扰。

public interface Phone {

  public void operate();

}

public class IPhone1 implement Phone {

  @Override

  public void operate() { system.out.println("拍照"); }

}

public class IPhone2 implement Phone {

  Phone phone;

  public IPhone2(Phone phone) {this.phone = phone; }

  @Override

  public void operate() {

    system.out.println("美颜");

    phone.operate();

  }

}

public class IPhone3 implement Phone {

  Phone phone;

  public IPhone3(Phone phone) {this.phone = phone; }

  @Override

  public void operate() {

    system.out.println("滤镜");

    phone.operate();

  }

}

调用:

Phone phone = new IPhone3(new IPhone2(new IPhone1()));

输出:

滤镜

美颜

拍照

 

6. 代理模式:代理模式分为三种,静态代理,JDK动态代理,CGLIB动态代理。代理模式是Spring中面向切面编程的核心。

6.1 静态代理

public interface Wo {

  public void Travel();

}

public class WoImpl implements Wo {

  @Override

  public void Travel() { Sysyem.out.println("去旅行"); }

}

public class MyProxyImpl implements Wo {

  private WoImpl woImpl = null;

  public MyProxyImpl(WoImpl woImpl) { this.woImpl = woImpl; } 

  @Override

  public void Travel() {

    Sysyem.out.println("订去返机票");

    Sysyem.out.println("打车去机场");

    woImpl.Travel();

  }

}

*要点:所谓代理就是在你执行某个动作前后,帮你做一些准备动作和收尾动作。静态代理类只能用于一个类的代理,扩展性差。

 

6.2 JDK动态代理

public class MyProxyImpl {
  public static Wo getMyProxyByJDK(Wo wo) {
    Wo myProxy = (Wo) Proxy.newProxyInstance(wo.getClass().getClassLoader(),
      wo.getClass().getInterfaces(),
      new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

          System.out.println("订去返机票");

          System.out.println("打车去机场");

          Object obj = method.invoke(wo, args);
          return obj;
        }
      });
    return myProxy ;
  }
}

 

7. 模板方法模式

先讲个小故事。大家在日常生活里,有空的时候都会自己做点饭吃。那么今天我想做个炒饭吃,明天我想做个炒面吃。其实炒饭和炒面基本上做法是一样的,只是主要食材不一样。

那么我只要能把炒饭做好了,炒面自然不在话下。

public abstract class ChaoTemplate {

  public void Do() {

    DaoYou();

    KaiHuo();

    ReYou();

    DaoShiCai();

    FanChao();

    GuanHuo();

  }

 

  public void DaoYou() { System.out.println("倒油"); }

  public void KaiHuo() { System.out.println("开火"); }

  public void ReYou() { System.out.println("热油"); }

  public abstract void DaoShiCai();

  public void FanChao() {System.out.println("翻炒"); }

  public void GuanHuo() { System.out.println("关火"); }

}

public  class ChaoFan extends ChaoTemplate {

  @Override

  public void DaoShiCai() { System.out.println(" 倒米饭"); }

}

public  class ChaoMian extends ChaoTemplate {

  @Override

  public void DaoShiCai() { System.out.println("倒面条"); }

}

public class Test {

  public static main(String[] args) {

    ChaoFan chaoFan = new ChaoFan();

    ChaoMian chaoMian = new ChaoMian();

    chaoFan.Do();

    chaoMian.Do();

  }

}

 *要点:其实就是将相同的动作提取出来放到父类里去实现,子类实现各自的不同工作。减少重复劳动。

 

8. 策略模式:定义一系列方法簇,具体实现类可以自己选择组合不同方法簇里的方法

public interface IMoveable {

  public void move();

}

public class OneStepOneMove implement IMoveable{

  @Override

  public void move() { system.out.println("一步一步走"); }

}

public class SpaceStepMove implement IMoveable{

  @Override

  public void move() { system.out.println("太空步"); }

}

public interface Biteable {

  public void bite();

}

public class OneStepOneBite implement Biteable{

  @Override

  public void bite() { system.out.println("一下一下咬"); }

}

public class HeadBite implement Biteable{

  @Override

  public void bite() { system.out.println("头撞"); }

}

public abstract class Zombie {

  public Zombie(IMoveable moveable, IBiteable biteable) {

    this.moveable = moveable;

    this.biteable = biteable;

  }

  private IMoveable moveable;

  private IBiteable biteable;

  public abstract void display();

  public void move() { moveable.move(); }

  public void bite() { biteable.bite(); }

}

public PuTongZombie extend Zombie {

  public PuTongZombie(IMoveable moveable, IBiteable biteable) {

    super(moveable, biteable);

  }

  @Override

  public void display() { system.out.println("我是普通僵尸"); }

}

public BigZombie extend Zombie {

  public PuTongZBigZombieMoveable moveable, IBiteable biteable) {

    super(moveable, biteable);

  }

  @Override

  public void display() { system.out.println("我是大头僵尸"); }

}

 public class Test {

  public static void main(String[] args) {

    Zombie putongZombie = new PuTongZombie(new OneStepOneBite(), new OneStepOneBite());

    Zombie bigZombie = new BigZombie(new HeadBite(), new SpaceStepBite());

    putongZombie.display();

    putongZombie.move();

    putongZombie.bite();

    bigZombie.display();

    bigZombie.move();

    bigZombie.bite();

  }

}

输出:

我是普通僵尸

一步一步走

一下一下咬

我是大头僵尸

太空步

头撞

 

欢迎看官儿们留言补充和指正,谢谢下次见!

作者:秋末午后的阳光
来源链接:https://www.cnblogs.com/chenyixun/p/13140307.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/server/41876.html

分享给朋友:

“Java之常用设计模式(精简)” 的相关文章

一分钟搞定Java环境变量配置

一分钟搞定Java环境变量配置

对于学Java的人来说,成功配置环境变量是第一步,因为后期不论 你做什么工作,会发现都需要这些,接下来介绍如何安装与配置,我按照jdk1.6来说明,其他一致。 下载官网 首先将jdk安装好后进行配置。 右击“计算机”,右键打开“属性”,...

常用设计模式系列(四)—建造者模式

常用设计模式系列(四)—建造者模式

一、前言 “山不在高,有仙则名。水不在深,有龙则灵。斯是陋室,惟吾德馨。苔痕上阶绿,草色入帘青。谈笑有鸿儒,往来无白丁。可以调素琴,阅金经。无丝竹之乱耳,无案牍之劳形。南阳诸葛庐,西蜀子云亭。孔子云:何陋之有?” ​ ——《陋室铭》刘禹锡 ​ 唐代诗人刘禹锡使用短...

数据库相关(JDBC,存储过程,以及大文本数据处理,mvc设计模式)

数据库相关(JDBC,存储过程,以及大文本数据处理,mvc设计模式)

目录 1.jdbc总结(模板、八股文): 2.CallableStatement:调用 存储过程、存储函数...

Java打印车票主要学习Java的比较语句

直接上代码 public static void main(String[] args) { // TODO Auto-generated method stub //初始化 Scanner in=new Scanner(S...

在JAVA 中将堆与栈分开的原因

栈是运行时的单位,而堆是存储的单位。 栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;堆解决的是数据存储的问题,即数据怎么 放、放在哪儿。 注意:在Java中一个线程就会相应有一个线程栈与之对应 栈因为是运行单位,因此里面存储的信息都是跟...

Java开发手册精华总结

Java开发手册精华总结

阿里 Java 开发手册的思考总结 一个优秀的工程师和一个普通的工程师的区别,不是满天飞的架构图,他的功底体现在所写的每一行代码上。 -- 毕玄 1. 命名风格 【书摘】类名用 UpperCamelCase 风格,比如 DO/BO/VO...

Java 容器 & 泛型:三、HashSet,TreeSet 和 LinkedHashSet比较

Java 容器 & 泛型:三、HashSet,TreeSet 和 LinkedHashSet比较

Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 上一篇总结了下ArrayList 、LinkedList和Vector比较,今天泥瓦匠总结下Hash 、LinkedList和Vector比较。其实大家都是...

java中的内部类总结

java中的内部类总结,包括静态内部类、私有内部类、方法内部类等 内部类不是很好理解,但说白了其实也就是一个类中还包含着另外一个类 如同一个人是由大脑、肢体、器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏:它也有自己的属性和行为(血液、跳动)...

java空指针异常:java.lang.NullPointException

一.什么是java空指针异常     我们都知道java是没有指针的,这里说的"java指针"指的就是java的引用,我们不在这里讨论叫指针究竟合不合适,而只是针对这个异常本身进行分析。空指针就是空引用,java空指针异常就是引用本身为空,却调用了方...

Java并发之AQS详解

Java并发之AQS详解

java、多线程、并发、AbstractQueuedSynchronized、AQS、Lock、Mutex、ReentrantLock、Semaphore、CountDownLatch、线程同步 一、概述   谈到并发,不得不谈ReentrantLock;而谈到...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。