Java设计模式中的几种常用设计模式总结
一、设计模式概念
1、定义
Java包含23种设计模式,是一套对代码设计经验的总结,被人们反复利用,多人熟知的代码设计方式。
2、目的
为了提高代码的可读性,可扩展性以及代码的复用性,为了解决在写代码过程中遇到的代码设计问题。
3、设计模式的六大原则
3.1开闭原则
对扩展开放,对修改关闭(尽可能对代码少修改)
3.2里氏替换原则
它是面向对象基本原则之一,任何父类(基类)出现的地方,子类都可以出现,也就是子类可以替换父类的任何功能(体现了父类的可扩展性)
3.3依赖倒转原则
尽可能面向接口编程,依赖接口而不依赖类
3.4接口隔离原则
一个类如果能实现多个接口,尽可能实现多个,为了降低依赖,降低耦合
3.5最少知道原则
一个实体尽可能少的与其他实体产生相互关联关系,将实体的功能独立
3.6合成复用原则
尽量使用合成,聚合的方式,而不使用继承
4、设计模式的分类
Java设计模式分为三大类
创建型模式:对象实例化的模式,创建型模式用于解耦对象的实例化过程。
结构型模式:把类或对象结合在一起形成一个更大的结构。
行为型模式:类和对象如何交互,及划分责任和算法。
如下图所示:

二、常用的几种设计模式
1、单例模式
单例模式是创建对象的一种特殊方式,程序从始至终都只创建一个对象叫单例(单实例)
分为两类
1.1、懒汉式单例
public class Person{
//为了不让其他类直接访问该成员 懒汉式单例,在使用时创建对象
//1、私有静态变量
private static Person person=null;
//2、将构造器私有化
private Person(){
}
//3、提供一个静态方法,并返回该类的对象
public static Person getInstance(){
if(person==null){
//第一次访问
person=new Person();;
}
return person;
}
public void sayHello(){
System.out.println("sayHello方法");
}
}
1.2、饿汉式单例
public class Student {
//1、 饿汉式单例模式, 在类加载时创建一个对象
private static Student student = new Student();
// 2 构造器私有化
private Student(){
}
// 3 提供返回类对象的静态方法
public static Student getInstance(){
if(student !=null){
return student;
}
return null;
}
}
2、工厂方法模式
创建对象的过程不再由当前类实例化,而是由工厂类完成,在工厂类中只需要告知对象类型即可。工厂模式中必须依赖接口
2.1简单工厂模式
简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。不修改代码的话,是无法扩展的。

以生产“电脑”为例,电脑有办公的功能,可以生产一体机或笔记本
代码与静态工厂一样
2.2静态工厂模式

//电脑接口
public interface Computer {
//电脑办公
public void work();
}
//笔记本
public class PersonComputer implements Computer{
@Override
public void work() {
System.out.println("这是笔记本电脑,正在办公");
}
}
//一体机
public class WorkComputer implements Computer{
@Override
public void work() {
System.out.println("这是一体机正在办公");
}
}
//用于生产电脑的工厂 (这个工厂既可以生产台式机也可以生产笔记本)
public class ComputerFactory {
/**
* 根据不同的类型 生产不同的产品
* @param type
* @return
*/
public Computer produce(String type){
Computer computer =null;
if(type.equals("personComputer")){
computer = new PersonComputer();
}else if(type.equals("workComputer")){
computer = new WorkComputer();
}else{
System.out.println("不能生产");
}
return computer;
}
//静态工厂方法模式
public class ComputerFactory2 {
/**
* 静态工厂方法
* @param type
* @return
*/
public static Computer produce(String type){
// 定义一个接口的引用 通过接口new 一个实现类的对象
// 提高扩展性
Computer computer=null;
if(type.equals("workComputer")){
computer = new WorkComputer();
}else if(type.equals("personComputer")){
computer = new PersonComputer();
}else{
System.out.println("不能创建对象");
}
return computer;
}
}
//测试类
public class Test1 {
public static void main(String[] args) {
// 通过工厂类创建对象
ComputerFactory factory = new ComputerFactory();
// 要对象 找工厂
Computer computer1 = factory.produce("workComputer");
computer1.work();
// 创建笔记本
Computer computer2 = factory.produce("personComputer");
computer2.work();
Computer computer3 = ComputerFactory2.produce("workComputer");
computer3.work();
}
}
3.3工厂方法模式
工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。在同一等级结构中,支持增加任意产品。

例如:

//汽车接口
public interface Car {
public void showInfo();
}
public class AudiCar implements Car {
@Override
public void showInfo() {
System.out.println("这是一台奥迪汽车。。");
}
}
public class BMWCar implements Car {
@Override
public void showInfo() {
System.out.println("这是一台宝马汽车。");
}
}
/**
生产汽车的工厂接口
**/
public interface CarFactory {
public Car produce();
}
public class AudiCarFactory implements CarFactory {
@Override
public Car produce() {
return new AudiCar();// 这里AudiCar是Car的实现类
}
}
public class BMWCarFactory implements CarFactory {
@Override
public Car produce() {
return new BMWCar();// 因为BWMCar是Car的实现类
}
}
public class Test1 {
public static void main(String[] args) {
//先创建 汽车工厂
CarFactory bmwFactory = new BMWCarFactory();
// 这个工厂生产的汽车就是 宝马
Car bmw = bmwFactory.produce();
bmw.showInfo();
//这个模式对于同一级别的产品,可扩展性高
//可以扩展不同品牌的汽车,此时不需要修改代码,只需要增加代码即可
// 创建一个新的品牌汽车 大众汽车
CarFactory dazhongFactory = new DazhongCarFactory();
Car car = dazhongFactory.produce();
car.showInfo();
}
}
3、抽象工厂模式
对于在工厂方法的基础上,对同一个品牌的产品有不同的分类,并对分类产品创建的过程 ,一个汽车产品 会分为不同的种类(迷你汽车 ,SUV汽车 )

/**
* 迷你汽车接口
*/
public interface MiniCar {
public void showInfo();
}
/**
* SUV汽车接口
*/
public interface SUVCar {
public void showInfo();
}
public class AudiMiniCar implements MiniCar {
@Override
public void showInfo() {
System.out.println("这是奥迪迷你汽车 ");
}
}
public class BMWMiniCar implements MiniCar {
@Override
public void showInfo() {
System.out.println("这是宝马Cooper迷你汽车");
}
}
public class AudiSUVCar implements SUVCar {
@Override
public void showInfo() {
System.out.println("这是一辆 奥迪SUV汽车");
}
}
public class BMWSUVCar implements SUVCar {
@Override
public void showInfo() {
System.out.println("这宝马的SUV系列");
}
}
public interface CarFactory {
//生成不同型号的汽车 ,两条产品线
public MiniCar produceMiniCar();
public SUVCar produceSUVCar();
}
public class AudiCarFactory implements CarFactory {
@Override
public MiniCar produceMiniCar() {
return new AudiMiniCar();
}
@Override
public SUVCar produceSUVCar() {
return new AudiSUVCar();
}
}
public class BMWCarFactory implements CarFactory {
// 生成迷你汽车的方法,返回MiniCar
@Override
public MiniCar produceMiniCar() {
return new BMWMiniCar();
}
//生成SUV汽车的方法, 返回SUVCar
@Override
public SUVCar produceSUVCar() {
return new BMWSUVCar();
}
}
/**
* 测试类
*/
public class Test1 {
public static void main(String[] args) {
//创建宝马迷你汽车 找工厂
CarFactory factory = new BMWCarFactory();
MiniCar car = factory.produceMiniCar();
car.showInfo();
}
}
总结:对于简单工厂,工厂方法模式和抽象工厂的区别和用途
小结:
★工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。
★使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。
★工厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。
区别:
1、对于简单工厂,用于生产同一结构中的任意产品,对于新增产品不适用。
2、对于工厂方法,在简单工厂的基础上,生产同一等级结构中笃定产品,可以支持新增产品。
3、抽象工厂,用于生产不同种类(品牌)的相同类型(迷你,SUV),对于新增品牌可以,不支持新增类型
8、模板方法
定义:
模板方法是一种行为模式,父类的一个方法定义完成这个方法的步骤,但不具体实现具体细节,由子类完成各个步骤的实现,在创建子类对象时,最终实现过程是子类的方法。
模板方法的准备:
1、继承关系
2、父类是抽象类:抽象类实现了模板方法,定义了算法的估计
3、子类继承抽象类:实现抽象方法,完成完整的算法
public abstract class AbstractPerson {
/**
* 定义一个模板方法,用于实现这个方法的基本“骨架”
* 每一步骤的具体实现由子类完成
*/
public void preparedSchool(){
getUp();
dressing();
eat();
}
//起床
public abstract void getUp();
//穿衣服
public abstract void dressing();
//吃早餐
public abstract void eat();
}
public class Student extends AbstractPerson {
@Override
public void getUp() {
System.out.println("学生起床,起不来,闹钟响3次");
}
@Override
public void dressing() {
System.out.println("学生穿衣服,找不到衣服");
}
@Override
public void eat() {
System.out.println("学生吃早餐,来不及吃早餐");
}
}
public class Teacher extends AbstractPerson {
@Override
public void getUp() {
System.out.println("老师起床,7点半起床");
}
@Override
public void dressing() {
System.out.println("老师要衣服得体,穿工装");
}
@Override
public void eat() {
System.out.println("老师吃早餐。");
}
}
public class Test1 {
public static void main(String[] args) {
Student stu = new Student();
stu.preparedSchool();
Teacher teacher = new Teacher();
teacher.preparedSchool();
}
}
Java设计模式中的几种常用设计模式总结的更多相关文章
- [ 转载 ] Java开发中的23种设计模式详解(转)
Java开发中的23种设计模式详解(转) 设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类 ...
- C++源码实现:21种常用设计模式
C++源码实现:21种常用设计模式一直以来在设计模式的学习中,都是出现java的源码,这对学习C++的极度不友好.本工程是基于C++实现21种常用的设计模式,里面包含了实例代码和示例.编写的时候在学习 ...
- javaEE Design Patter(1)初步了解23种常用设计模式
设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. ...
- 23种常用设计模式的UML类图
23种常用设计模式的UML类图 本文UML类图参考<Head First 设计模式>(源码)与<设计模式:可复用面向对象软件的基础>(源码)两书中介绍的设计模式与UML图. 整 ...
- 转载:23种常用设计模式的UML类图
转载至:https://www.cnblogs.com/zytrue/p/8484806.html 23种常用设计模式的UML类图 本文UML类图参考<Head First 设计模式>(源 ...
- java线程池与五种常用线程池策略使用与解析
背景:面试中会要求对5中线程池作分析.所以要熟知线程池的运行细节,如CachedThreadPool会引发oom吗? java线程池与五种常用线程池策略使用与解析 可选择的阻塞队列BlockingQu ...
- java线程池和五种常用线程池的策略使用与解析
java线程池和五种常用线程池策略使用与解析 一.线程池 关于为什么要使用线程池久不赘述了,首先看一下java中作为线程池Executor底层实现类的ThredPoolExecutor的构造函数 pu ...
- java多线程中的三种特性
java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...
- SuperDiamond在JAVA项目中的三种应用方法实践总结
SuperDiamond在JAVA项目中的三种应用方法实践总结 1.直接读取如下: @Test public static void test_simple(){ PropertiesConfigur ...
- Java开发中的23种设计模式详解
[放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...
随机推荐
- os模块的使用方法详解
os模块 os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口:即os模块提供了非常丰富的方法用来处理文件和目录. 使用的时候需要导入该模块:import os 常用方法如下: 方法名 作用 ...
- MySQL高可用架构-MMM、MHA、MGR、分库分表
总结 MMM是是Perl语言开发的用于管理MySQL主主同步架构的工具包.主要作用:管理MySQL的主主复制拓扑,在主服务器失效时,进行主备切换和故障转移. MMM缺点:故障切换可能会丢事务(主备使用 ...
- golang pprof 监控系列(1) —— go trace 统计原理与使用
golang pprof 监控系列(1) -- go trace 统计原理与使用 服务监控系列文章 服务监控系列视频 关于go tool trace的使用,网上有相当多的资料,但拿我之前初学golan ...
- [C++STL教程]2.queue队列容器,小白都能看懂的讲解!
在学习数据结构的时候我们会听到这样一个词:队列. 本文将介绍STL中的队列:queue 本文仅从入门和实用角度介绍queue的用法,主要针对初学者或竞赛向.如有不严谨的地方欢迎指正!本文长度约2000 ...
- Rancher 系列文章-K3s Traefik MiddleWare 报错-Failed to create middleware keys
概述 书接上回:<Rancher 系列文章-K3S 集群升级>, 我们提到:通过一键脚本升级 K3S 集群有报错. 接下来开始进行 Traefik 报错的分析和修复, 问题是: 所有 Tr ...
- Python爬虫基础教程2
beautifulsoup4介绍/遍历文档树 bs4 > 从html或xml文件中提取的python库 用它来解析爬取回来的xml 安装:pip install beautifulsoup4 p ...
- 和 chatgpt 聊了一会儿分布式锁 redis/zookeeper distributed lock
前言 最近的 chatGPT 很火爆,听说取代程序员指日可待. 于是和 TA 聊了一会儿分布式锁,我的感受是,超过大部分程序员的水平. Q1: 谈一谈 java 通过 redis 实现分布式 锁 ch ...
- Yii framework 应用小窍门
Yii framework 应用小窍门 1. Yii Framework] 如何获取当前controller的名称? 下面语句就可以获取当前控制器的名称了! Php代码 Yii::app ...
- React课堂笔记1
一.概要 React是用于构建用户界面的MVVM框架. React拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它.认为它可能是将来Web开发的主流工具之一. 官网:https://z ...
- DataX更换python3,File “datax.py“, line 114 print readerRef
datax 报错 File "datax.py", line 114 print readerRef 报错: File "datax.py", line 114 ...