全部章节   >>>>


本章目录

6.1 设计模式

6.1.1 设计模式概述和分类

6.1.2 单列模式介绍

6.1.3 单例模式的实现

6.1.4 实践练习

6.2 单例模式的应用

6.2.1 单例模式应用场景

6.2.2 单例模式的优缺点分析

6.2.3 实践练习

6.3 简单工厂模式

6.3.1 简单工厂模式的介绍

6.3.2 实践练习

6.4 简单工厂模式的应用

6.4.1 简单工厂模式的使用场景

6.4.2 简单工厂的优缺点分析

6.4.3 实践练习

总结:


6.1 设计模式

设计模式是由软件界的前辈们总结出的一套可以反复使用的经验。它可以提高代码的可重用性,增强系统的可维护性以及解决一系列的复杂问题。设计模式是思想的体现,而非具体的实现

合理的利用设计模式,能在项目中搭建出更加合理、优秀、可扩展的项目架构,这对于项目中的灵活度、可扩展性起着非常重要的作用

设计模式是成为一名优秀开发人员、项目经理必须修炼的内功基础

6.1.1 设计模式概述和分类

随着软件行业不断发展设计模式的种类也越来越多,不同的设计模式,对于不同种类的问题也有着不同的效果

常见的设计模式有以下类别:

创建模式(单例模式、工厂模式、抽象工厂模式、生成器模式、原型模式)

结构模式(适配器模式、桥接模式、组成模式、装饰模式、外观模式、享元模式、代理模式)

行为模式(中介者模式、命令模式、备忘录模式、状态模式、策略模式、解释器模式、迭代器模式、观察者模式、访问者模式、模板方法模式)

6.1.2 单列模式介绍

单例模式(Singleton)是对象的创建模式。单例模式确保某一个类只有一个实例,而且自行实例化,并向整个系统提供这个实例,这个类称为单例类 单例模式的要点有以下 3 个 单例类只能有一个实例。 单例类必须自行创建唯一的实例。 单例类必须向所有对象提供这一实例。

6.1.3 单例模式的实现

单例模式具体的实现步骤

1、私有化构造方法

public class  Singleton{
private Singleton(){
//第一步:构造方法私有化
}
}

构造方法私有化的目的是不让当前类范围以外的地方实例化对象

2、在当前类中实例化本类对象

// 创建一个静态对象
private static Singleton instance = new Singleton();

当前类以外不能实例化,但是当前类自己可以实例化,保证只实例化了一次, 外界都使用这一个对象即可。

3、提供给外界一个获取当前类对象的机会,该方法必须public static,这样外界通过类名可以调用该方法

// 创建一个获取静态对象的共有静态方法
public static Singleton getInstance() {
return instance;
}

第二步创建当前类对象时使用了private,目的是保护它,然后该类中提供公共静态方法对其进行访问获取

示列: 使用单例设计模式实现类的单例控制

public class Singleton {
// 创建一个静态对象
private static Singleton instance = new Singleton();
// 私有化构造方法
private Singleton() { }
// 创建一个获取静态对象的共有静态方法
public static Singleton getInstance() {
return instance;}
}
public static void main(String[] args) {
// 创建 3 个 Singleton 对象
Singleton instance01 = Singleton.getInstance();
Singleton instance02 = Singleton.getInstance();
Singleton instance03 = Singleton.getInstance();
System.out.println(instance01);
System.out.println(instance02);
System.out.println(instance03);}

6.1.4 实践练习

6.2 单例模式的应用

6.2.1 单例模式应用场景

在一个系统中,有时会要求一个类有且仅有一个对象,如果存在多个对象就会出现“不良反应”,可以采用单例模式(Singleton)来解决这个问题

  • 在整个项目中,需要一个共享访问点或共享数据,保证不同用户不同时间访问的都是同一个数据
  • 创建对象需要消耗的资源过多,而该对象每次使用时功能均一样,没必要重复创建
  • 需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式

示列:某公司内只有一台打印机,供所有员工使用,使用单例模式模拟该打印机的单例。

public class CompanyPrinter {
// 私有化构造方法
private CompanyPrinter() {
}
// 创建静态内部类,该内部类的实例与外部类的实例没有绑定关系,该内部类只有被调用时才可加载,从而实现了延迟加载
private static class PrinterHolder {
// 创建 Printer 静态实例
private static CompanyPrinter printer = new CompanyPrinter();
}
// 返回静态内部类中创建的静态私有对象
public static CompanyPrinter getInstance() {return PrinterHolder.printer;}
}
public class Employee {
public static void main(String[] args) {
CompanyPrinter printer01 = CompanyPrinter.getInstance();
System.out.println(" 员工 1 使用打印机:" + printer01);
CompanyPrinter printer02 = CompanyPrinter.getInstance();
System.out.println(" 员工 2 使用打印机:" + printer02);
CompanyPrinter printer03 = CompanyPrinter.getInstance();
System.out.println(" 员工 3 使用打印机:" + printer03);}
}

6.2.2 单例模式的优缺点分析

单例模式也并非是完美的,也存在一些优点和缺点

优点:

  • 项目中只有一个实例,减少了内存开支
  • 单例模式只生成一个实例,所以减少了系统的性能开销
  • 单例模式可以避免对资源的多重占用,比如读一个文件时,保证其他程序无法写入等

缺点:

  • 单例模式一般没有接口,扩展很困难,若要扩展,除了修改代码
  • 单例模式对测试是不利的
  • 单例模式与单一职责原则有冲突

6.2.3 实践练习

6.3 简单工厂模式

6.3.1 简单工厂模式的介绍

简单工厂模式的目的在于不知道创建对象的细节,而能根据需要得到所对应的对象

简单工厂模式是类的创建模式,这个模式的一般性结构如下图所示

简单工厂模式涉及到工厂(Creator)、抽象产品(Product)以及具体产品(ConcreteProduct),各个角色的职责

工厂:这是简单工厂模式的核心,由它负责创建所有的类的内部逻辑。工厂类必须能够被外界调用,创建所需要的产品对象

抽象产品:简单工厂模式所创建的所有对象的父类,注意,这里的父类可以是接口也可以是抽象类,它负责描述所有实例所共有的公共接口

具体产品:简单工厂所创建的具体实例对象,这些具体产品的类都是抽象产品的子类

示例:简单工厂实现步骤1:定义抽象产品父类

// 抽象接口
public interface Api {
// 具体方法的定义
public void operation(String s);
}

抽象产品的父类可以使用接口或者抽象类,但是需要有抽象方法

示例:简单工厂实现步骤2:定义具体子类产品

// 接口的具体实现产品A
public class ImpA implements Api {
//方法重写
public void operation(String s) {
System.out.println(" 实现接口 Api 的具体类 ImpA:" + s);
}
// 接口的具体实现产品B
public class ImpB implements Api {
//方法重写
public void operation(String s) {
System.out.println(" 实现接口 Api 的具体类 ImpB:" + s);
}

现在有两个具体的产品类都是抽象产品的子类:A产品和B产品,当然还可以有更多。

示例:简单工厂实现步骤3:定义简单工厂返回具体对象

// 工厂类
public class Factory {
// 创建 Api 对象的方法
public static Api createApi(int condition) {
Api api = null;
// 根据传来的条件选择创建哪个对象
if (condition == 1) {api = new ImpA();}
else if (condition == 2) {api = new ImpB(); }
return api; }
}

示例:简单工厂实现步骤4:使用者调用测试

public class Client {
public static void main(String[] args) {
Api api = Factory.createApi(2);
api.operation(" 正在使用简单工厂 ");
}
}

使用者可以传入条件,拿到自己想要的对象,具体如何创建的对象,则无需使用者关心,使用者只知道自己拿到对象可以使用即可。

6.3.2 实践练习

6.4 简单工厂模式的应用

6.4.1 简单工厂模式的使用场景

简单工厂的目的在于隐藏创建对象的过程,让调用者无需关心对象的创建过程,而是直接拿到可以使用的对象,提高项目对象获取的灵活性,建议在以下场景时选择简单工厂模式

  • 想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选用简单工厂模式
  • 想要把对外创建对象的职责集中管理和控制,可以选用简单工厂,一个简单工厂可以创建很多不相关的对象,可以把对外创建对象的职责集中到一个简单工厂来,从而实现集中管理和控制

示例:

  • 假设一个场景:魅族、VIVO 和 OPPO 都是有名的国产智能手机品牌,有一家手机代工厂的主营业务,是为魅族、VIVO 和 OPPO 这三家公司生产手机
  • 当魅族公司的订单到来时,工厂就要生产魅族手机;当 VIVO 公司的订单到来时,工厂就要生产 VIVO 手机;
  • 当 OPPO 公司的订单到来时,工厂就要生产 OPPO 手机 工厂要生产什么品牌的手机,完全由订单来决定。那该如何用程序来模拟这个场景?

可以发现该场景有 3 个角色,分别是手机代工厂、手机订单和各个品牌的手机订单,可以使用简单工厂的 3 个角色来表示。手机代工厂是工厂,订单是抽象产品,各个公司下发的订单就是具体产品

6.4.2 简单工厂的优缺点分析

简单工厂虽然对于单一产品的创建,在灵活性方面提高了灵活度,但是在复杂产品集方面的扩展性仍然有很多不足

优点:

  • 简单工厂模式虽然很简单,但是非常友好地帮助我们实现了组件的封装,然后让组件外部能真正面向接口编程
  • 通过简单工厂模式,实现了客户端和具体实现类的解耦

缺点

  • 客户必须了解参数对应产品的关系,增加客户端使用的难度,也暴露了内部逻辑的实现过程
  • 每当添加一个具体产品类时,都需要修改工厂角色类,增加了工作量

6.4.3 实践练习

总结:

  • 设计模式是软件界的前辈们总结出的一套可以反复使用的经验,它可以提高代码的可重用性,增强系统的可维护性,还能解决一系列的复杂问题
  • 单例模式是保证项目中某个类永远只存在一个对象的设计模式,可以降低某些只需要加载一次的重量级对象创建过程,避免多次创建引起的不必要开销
  • 简单工厂模式的目的是对于使用者完全不必知道创建对象的细节,而能根据需要得到所对应的对象的过程,提高了获取对象的灵活性
  • Java中常用的设计模式有23种,掌握常用的设计模式对于我们成为优秀的开发人员和项目经理又进了一步

Java高级程序设计笔记 • 【第6章 设计模式】的更多相关文章

  1. Java高级程序设计笔记 • 【目录】

    持续更新中- 我的大学笔记>>> 章节 内容 实践练习 Java高级程序设计作业目录(作业笔记) 第1章 Java高级程序设计笔记 • [第1章 IO流] 第2章 Java高级程序设 ...

  2. Java高级程序设计笔记 • 【第5章 XML解析】

    全部章节   >>>> 本章目录 5.1 XML 文档概述 5.1.1 XML文档结构 5.1.1 XML结构说明 5.1.1 XML文档元素 5.1.2 XML文档语法规范 ...

  3. Java高级程序设计笔记 • 【第4章 网络编程】

    全部章节   >>>> 本章目录 4.1 网络基础知识 4.1.1 IP地址 4.1.2 端口号 4.1.3 使用InetAddress 4.1.4 InetAddress 类 ...

  4. Java高级程序设计笔记 • 【第3章 多线程(二)】

    全部章节   >>>> 本章目录 3.1 同步代码块 3.1 线程安全 3.1.1 模拟银行取款 3.1.2 同步代码块的使用 3.1.3 实践练习 3.2 同步方法 3.2. ...

  5. Java高级程序设计笔记 • 【第2章 多线程(一)】

    全部章节   >>>> 本章目录 2.1 线程的概述 2.1.1 进程 2.1.2 多线程优势 2.1.3 Thread 类 2.1.4 实践练习 2.2 Runnable接口 ...

  6. Java高级程序设计笔记 • 【第1章 IO流】

    全部章节   >>>> 本章目录 1.1 File类访问文件 1.1.1 File 类 1.1.2 File 类方法 1.1.3 实践练习 1.2 文件过滤器 1.2.1 Fi ...

  7. Javascript高级程序设计笔记 <第五章> 引用类型

    一.object类型 创建object实例的方式有两种: //第一种使用new操作符跟构造函数 var person= new Object(); person.name="小王" ...

  8. Java高级程序设计作业目录(作业笔记)

    持续更新中............. Java高级程序设计笔记 • [目录] 我的大学笔记>>> 第1章 IO流>>> 1.1.3 编写Java程序,在电脑硬盘里, ...

  9. Java Web程序设计笔记 • 【目录】

    章节 内容 实践练习 Java Web程序设计作业目录(作业笔记) 第1章 Java Web程序设计笔记 • [第1章 Web应用程序] 第2章 Java Web程序设计笔记 • [第2章 JSP基础 ...

随机推荐

  1. Output of C++ Program | Set 8

    Predict the output of following C++ programs. Question 1 1 #include<iostream> 2 using namespac ...

  2. spring 事务处理中,同一个类中:A方法(无事务)调B方法(有事务),事务不生效问题

    public class MyEntry implements IBaseService{ public String A(String jsonStr) throws Exception{ User ...

  3. 增大Oracle Virtualbox的磁盘空间

    https://blog.csdn.net/hiyachen/article/details/102131823 背景 在virtualbox中装好Linux以及Application之后,发现硬盘空 ...

  4. hadoop Sort排序

    1 public int getPartition(IntWritable key,IntWritable value,int numPartitions){ 2 int Maxnumber = 12 ...

  5. 从orderby引发的SQL注入问题的思考

    背景: 某一天准备上线,合完master之后准备发布了,忽然公司的代码安全监测提示了可能在代码中存在sql注入的风险,遂即检查,发现sql注入问题 既然碰到了这个问题,那就了简单了解下sql注入 基础 ...

  6. 【经验分享】win10 cmake 构建 Tengine 工程

      欢迎关注我的公众号 [极智视界],回复001获取Google编程规范   O_o   >_<   o_O   O_o   ~_~   o_O   本教程详细记录了在 win10 环境中 ...

  7. 如何使用cURL获得请求/响应具体耗时?

    如何使用cURL一次测量请求和响应时间? cURL支持格式化输出请求的详细信息(请参阅cURL手册页的-w.–write out<format>获取更多信息). 如题,我们将只关注如何知晓 ...

  8. [BUUCTF]REVERSE——[GWCTF 2019]xxor

    [GWCTF 2019]xxor 附件 步骤: 无壳,64位ida载入 程序很简单,首先让我们输入一个字符串,然后进行中间部分的操作,最后需要满足44行的if判断,看一下sub_400770函数 得到 ...

  9. how2heap学习(二)

    拖了好久,但是在期间做了几道pwn题目,发现堆原来也没有想象中的难. fastbin_dup_into_stack 这个说白了,就是利用double free可以进行任意地址的写,说是任意地址不准确, ...

  10. 【Web】BUUCTF-warmup(CVE-2018-12613)

    BUUCTF 的第一题,上来就给搞懵了.. .这要是我自己做出来的,岂不是相当于挖了一个 CVE ?(菜鸡这样安慰自己)   问题在 index.php 的 55~63 行 // If we have ...