Windows环境下实现设计模式——模板方法模式(JAVA版)

news2024/11/18 15:25:47

 我是荔园微风,作为一名在IT界整整25年的老兵,今天总结一下Windows环境下如何编程实现模板方法模式(设计模式)。

不知道大家有没有这样的感觉,看了一大堆编程和设计模式的书,却还是很难理解设计模式,无从下手。为什么?因为你看的都是理论书籍。

我今天就在Windows操作系统上安装好JAVA的IDE编程工具,并用JAVA语言来实现一个模板方法模式,真实的实现一个,你看懂代码后,自然就明白了。

模板方法模式Template Method Pattern  (行为型设计模式)

定义:定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

上面定义听懂了吗?莫名其妙看不懂对吧。所以我们还是来看看实现生活中的例子。

模板方法模式是结构最简单的行为型设计模式,它是一种类行为模式,在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式可以将一些复杂流程的实现步骤封装在一系列基本方法中,在抽象父类中提供了一个称为模板方法的方法来定义这些基本方法的执行次序,而通过其子类来覆盖某些步骤,从而使得相同的算法框架可以有不同的执行结果。它提供了具体的模板方法来定义算法结构,而具体步骤的实现可以在其子类中完成。

现在开始举例:柔性制造

生产,顾名思义,就是富有弹性和灵活性的生产方式,精益生产即是柔性生产精髓的表现。柔性生产建立在柔性制造的基础上,以市场为导向,按需生产,能够增强企业的灵活性和应变能力,提高生产效率,缩短生产周期,帮助企业适应多变的市场需求和激烈的市场竞争,具有强大的生命力。

“柔性”是 相对于“刚性”而言的,传统的“刚性”自动化生产线主要实现单一品种的大批量生产,而“柔性”生产线则更能够满足当今消费者个性化、多样化的需求。

一、柔性制造的基本特征

1、机器柔性:当要求生产一系列不同类型的产品时,机器随产品变化而加工不同零件的难易程度。

2、工艺柔性:系统能够根据加工对象的变化或原材料的变化而确定相应的工艺流程,其中一是工艺流程不变时自身适应产品或原材料变化的能力;二是制造系统内为适应产品或原材料变化而改变相应工艺的难易程度。

3、产品柔性:一是产品更新或完全转向后,系统能够非常经济和迅速地生产出新产品的能力;二是产品更新后,对老产品有用特性的集成能力和兼容能力。

4、维护柔性:系统能够采用多种方式查询、处理故障,保障生产正常进行。

5、生产能力柔性:当生产量改变时,系统也能经济地运行的能力。对于根据订货而组织生产的制造系统,这一点尤为重要。

6、扩展柔性:当生产需要的时候,可以容易地扩展系统结构,增加模块,构成一个更大系统的能力。

7、运行柔性:利用不同的机器、材料、工艺流程来生产一系列产品的能力和同样的产品,换用不同工序加工的能力。

总而言之,柔性生产的核心是柔性制造技术,而柔性制造技术是对各种不同形状加工对象实现程序化柔性制造加工的各种技术的总和。柔性制造技术是技术密集型的技术群,我们认为凡是侧重于柔性、适应于多品种、中小批量(包括单件产品)的加工技术都属于柔性制造技术。

二、柔性制造的基本功能

1、能够自动控制和管理零件的加工过程,包括制造质量的自动控制、故障的自动诊断和处理、制造信息的自动采集和处理。2、通过简单的软件系统变更,便能制造出某一零件族的多种零件。3、自动控制和管理物料(包括工件与刀具)的运输和存储过程。4、能解决多机床下零件的混流加工,且无需增加额外费用。5、具有优化的调度管理功能,无需过多的人工介入,能做到无人加工。

三、什么是柔性制造系统

根据我国国家军用标准,柔性制造系统是由数控加工设备、物料运储装置和计算机控制系统组成的自动化制造系统,它包括多个柔性制造单元,能根据制造任务或生产环境的变化迅速进行调整,适用于多品种、中小批量生产。简单来说,FMS是由若干数控设备、物料运储装置和计算机控制系统组成的,并且能够根据制造任务和生产品种变化而迅速进行调整的自动化制造系统。

目前常见的组成通常包括4台或更多台全自动数控机床(加工中心与车削中心等),由集中的控制系统及物料搬运系统连接起来,可在不停机的情况下实现多品种、中小批量的加工及管理。

四、柔性制造系统的优点

1、提高了设备利用率:通过计算机把每个零件安排了相应的加工机床,该机床空闲时就马上将零件送上加工,尽量使制造系统中的加工设备都得到利用。由于设备的利用率高,能以较少的设备达到传统生产线的产量,从而降低了设备的投资成本。

2、提高了生产的应变能力:当今的消费者的需求更加个性化和多样化,而柔性制造系统有其内在的灵活性,能适应由于市场需求变化和工程设计变更所出现的变动,进行多种产品的生产。而且能够在不明显打乱正常生产计划的情况下,插入备件和急件制造任务。

3、提高了生产效率:因为柔性制造更看重需求,其实属于按照需求生产的拉动型生产模式。不需要浪费大量时间等待之前的工序加工完成,从而缩短了生产制造的时间,提高了生产效率。除此之外,还能减少库存量,节约进行储存的仓库成本。

五、柔性制造系统的核心技术

1、计算机辅助设计

2、模糊控制技术

3、人工智能、专家系统及智能传感器技术

4、人工神经网络技术

5、综合控制系统

以上技术就不做介绍了,大家感兴趣的话可以自行查阅哦。

总结

柔性制造技术是实现未来工厂的新概念模式和新的发展趋势,是决定制造企业未来发展前途的具有战略意义的举措。届时,智能化机械与人之间将相互融合,柔性地全面协调从接受订货单至生产、销售这一企业生产经营的全部活动。所以生产一个产品,往往简化后就是:原料——生产——产品

这个步骤中,原料和产品的工序变化不大,但中间这个生产步骤区别就大了,为了满足柔性制造的要求,生产这个步骤差别会很大很大。

在软件开发中,某个方法的实现需要多个步骤(类似“柔性制造”),其中有些步骤是固定的(类似“原料”和“产品”),而有些步骤并不固定,存在可变性(类似“生产”)。为了提高代码的复用性和系统的灵活性,可以使用一种称之为模板方法模式的设计模式来对这类情况进行设计,在模板方法模式中,将实现功能的每一个步骤所对应的方法称为基本方法(例如“原料——生产——产品”),而调用这些基本方法同时定义基本方法的执行次序的方法称为模板方法(例如“柔性制造”)。在模板方法模式中,可以将相同的代码放在父类中,例如将模板方法“柔性制造”以及基本方法“原料”和“产品”的实现放在父类中,而对于基本方法“生产”,在父类中只做一个声明,将其具体实现放在不同的子类中,在一个子类中提供“第一种生产方法”的实现,而另一个子类提供“第二种生产方法”的实现。通过使用模板方法模式,一方面提高了代码的复用性,另一方面还可以利用面向对象的多态性,在运行时选择一种具体子类,实现完整的“柔性制造”方法,提高系统的灵活性和可扩展性。
 

模板方法模式包含如下两个角色: (1) AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。  (2) ConcreteClass(具体子类):它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。

在实现模板方法模式时,开发抽象类的软件设计师和开发具体子类的程序员之间可以进行协作。一个设计师负责给出一个算法的轮廓和框架,程序员则负责给出这个算法的各个逻辑步骤。实现这些具体逻辑步骤的方法即为基本方法,而将这些基本方法汇总起来的方法即为模板方法。下面介绍模板方法和基本方法:
 

1. 模板方法

 一个模板方法是定义在抽象类中的、把基本操作方法组合在一起形成一个总算法或一个总行为的方法。这个模板方法定义在抽象类中,并由子类不加以修改地完全继承下来。模板方法是一个具体方法,它给出了一个顶层逻辑框架,而逻辑的组成步骤在抽象类中可以是具体方法,也可以是抽象方法。由于模板方法是具体方法,因此模板方法模式中的抽象层只能是抽象类。

2. 基本方法

基本方法是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:

 (1) 抽象方法:一个抽象方法由抽象类声明、由其具体子类实现。在Java和C#语言里一个抽象方法以abstract关键字标识。

 (2) 具体方法:一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。

 (3) 钩子方法:一个钩子方法由一个抽象类或具体类声明并实现,而其子类可能会加以扩展。通常在父类中给出的实现是一个空实现(可使用virtual关键字将其定义为虚函数),并以该空实现作为方法的默认实现,当然钩子方法也可以提供一个非空的默认实现。

好了,这里会有点难度,请大家耐心看完。Hook(钩子)是一种特殊的消息处理机制,它可以监视系统或者进程中的各种事件消息,截获发往目标窗口的消息并进行处理。所以说,我们可以在系统中自定义钩子,用来监视系统中特定事件的发生,完成特定功能,如屏幕取词,监视日志,截获键盘、鼠标输入等等。钩子来源于英文词hook。在Windows系统中一切皆消息,按键盘上的键,也是一个消息。Hook 的意思是钩住,也就是在消息过去之前,先把消息钩住,不让其传递,使用户可以优先处理。执行这种操作的函数也称为钩子函数。简单地讲,就是“要想从这过,留下买路钱”。即执行某操作之前,优先处理一下,再决定后面的执行走向。程序中需要监视的动作都可以调用,但运用的时候也要考虑资源问题。比如:激活,建立,销毁,最小化,最大化,移动,改变尺寸等窗口事件;完成系统指令;来自系统消息队列中的移动鼠标,键盘事件;设置输入焦点事件;同步系统消息队列事件。

在模板方法模式中,钩子方法有两类:第一类钩子方法可以与一些具体步骤“挂钩”,以实现在不同条件下执行模板方法中的不同步骤,这类钩子方法的返回类型通常是boolean类型的,这类方法名一般为isXXX(),用于对某个条件进行判断,如果条件满足则执行某一步骤,否则将不执行,如下代码片段所示:
 

……
//模板方法
public void TemplateMethod(){
    Open();
    Display();
    //通过钩子方法来确定某步骤是否执行
    if (isPrint()) {
        Print();
     }
}
 
//钩子方法
public bool isPrint(){
    return true;
}
……

在代码中isPrint()方法即是钩子方法,它可以决定Print()方法是否执行,一般情况下,钩子方法的返回值为true,如果不希望某方法执行,可以在其子类中覆盖钩子方法,将其返回值改为false即可,这种类型的钩子方法可以控制方法的执行,对一个算法进行约束。

还有一类钩子方法就是实现体为空的具体方法,子类可以根据需要覆盖或者继承这些钩子方法,与抽象方法相比,这类钩子方法的好处在于子类如果没有覆盖父类中定义的钩子方法,编译可以正常通过,但是如果没有覆盖父类中声明的抽象方法,编译将报错。在模板方法模式中,抽象类的典型代码如下:

public abstract class AbstractClass{
    //模板方法
    public void TemplateMethod() {
        PrimitiveOperation1();
        PrimitiveOperation2();
        PrimitiveOperation3();
    }
 
    //基本方法—具体方法
    public void PrimitiveOperation1(){
         //实现代码
    }
 
    //基本方法—抽象方法
    public abstract void PrimitiveOperation2();    
 
    //基本方法—钩子方法
    public virtual void PrimitiveOperation3()   
    { }
}

在抽象类中,模板方法TemplateMethod()定义了算法的框架,在模板方法中调用基本方法以实现完整的算法,每一个基本方法如PrimitiveOperation1()、PrimitiveOperation2()等均实现了算法的一部分,对于所有子类都相同的基本方法可在父类提供具体实现,例如PrimitiveOperation1(),否则在父类声明为抽象方法或钩子方法,由不同的子类提供不同的实现,例如PrimitiveOperation2()和PrimitiveOperation3()。

可在抽象类的子类中提供抽象步骤的实现,也可覆盖父类中已经实现的具体方法,具体子类的典型代码如下:

public class ConcreteClass : AbstractClass{
    public void PrimitiveOperation2() {
        //实现代码
    }
 
    public void PrimitiveOperation3() {
        //实现代码
    }
}

在模板方法模式中,由于面向对象的多态性,子类对象在运行时将覆盖父类对象,子类中定义的方法也将覆盖父类中定义的方法,因此程序在运行时,具体子类的基本方法将覆盖父类中定义的基本方法,子类的钩子方法也将覆盖父类的钩子方法,从而可以通过在子类中实现的钩子方法对父类方法的执行进行约束,实现子类对父类行为的反向控制。

应用实例

一家制造企业财务系统为不同的柔性生产线开发一个金额计算功能,计算流程如下:根据用户类型的不同使用不同的利息计算公式计算利息, 系统显示利息。Account充当抽象类角色,CurrentAccount和SavingAccount充当具体子类角色。

  (1) Account:账户类,充当抽象类。

package designpatterns.templatemethod;

public abstract class Account{
    //基本方法——具体方法
    public bool validate(string account, string password) {
	    System.out.println("账号:", account);
        System.out println("密码:", password);
        if (account.Equals("员工1") && password.Equals("123456")){
			    return true;
		    }
		    else{
			    return false;
		    }
	    }
 
    //基本方法——抽象方法
    public abstract void calculateInterest();
 
    //基本方法——具体方法
    public void display() {
          Console.WriteLine("显示");
    }
 
    //模板方法
    public void Handle(string account, string password) {
          if (!validate(account,password)) {
                 System.out println("账户或密码错误");
			     return;
		   }
		   calculateInterest();
		   display();
	    }
    }
}

   (2) CurrentAccount:活期账户类,充当具体子类。

package designpatterns.templatemethod;
 
public class CurrentAccount extends Account {
        //覆盖父类的抽象基本方法
        public void calculateInterest() 
        {
		    System.out.println("按活期利率计算利息");
	    }
    }
}

   (3) SavingAccount:定期账户类,充当具体子类。

package designpatterns.templatemethod;
 
public class SavingAccount extends Account {
        //覆盖父类的抽象基本方法
        public void calculateInterest() 
        {
		    System.out.println("按定期利率计算利息");
	    }
    }
}

   (4) 配置文件config.xml,在配置文件中存储了具体子类的类名。

<?xml version="1.0"?>
<config>
   <className>designpatterns.templatemethod.CurrentAccount</className>
</config>

(5)XMLUtil:工具类。
 

package designpatterns. templatemethod;

import javax. xml. parsers.*
import org.3c.dom.*;
import java.io.;

public class XMLUtil {
  //该方法用于从XML配置文件中提取具体类的类名,并返回一个实例对象
    public static Object getBean(){
      try {
         //创建DOM文档对象
         DocumentBuilderFactory dFactory = DocumentBuilderFactory. newInstance();
         DocumentBuilder builder = dFactory. newDocumentBuilder();
         Document doc;
         doc = builder. parse(new File("src//designpatterns//templatemethod//config. xml"));
    
          //获取包含类名的文本结点
        NodeList nl = doc. getElementsByTagName("className");
        Node classNode= nl. item(0). getFirstChild();
        String cName = classNode. getNodeValue();

        //通过类名生成实例对象并将其返回
        Class c= Class, forName(cName);
        Object obj=c. newInstance();
        return obj;
     }
    catch(Exception e){
         e. printStackTrace();
         return null;
      }
   }
}

(6)客户端测试类

package designpatterns. templatemethod;
 
public class Client {
       public static void Main(String[] args){
            Account account;
            //读取配置文件,反射生成对象
            account = (Account)XMLUtil.getBean();
            account.Handle("员工1", "123456");
        }   
}

总结一下,在以下情况下可以考虑使用模板方法模式:

 (1) 对一些复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法和父类具体方法,而一些可以改变的细节由其子类来实现。一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。 (2) 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。(3) 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。
 

各位小伙伴,这也是我的设计模式帖子《Windows环境下实现设计模式》的最后一期,以后不再写这个话题了,感觉好像设计模式的帖子没什么人爱看。也许是因为太难了,也许是因为别人写的相关帖子更好看。无论如何,这是《Windows环境下实现设计模式》的最后一期了。以后我写的编程帖子里如果有涉及到设计模式的,我肯定还会详细介绍的,希望对大家学习有帮助。

作者简介:荔园微风,1981年生,高级工程师,浙大工学硕士,软件工程项目主管,做过程序员、软件设计师、系统架构师,早期的Windows程序员,Visual Studio忠实用户,C/C++使用者,是一位在计算机界学习、拼搏、奋斗了25年的老将,经历了UNIX时代、桌面WIN32时代、Web应用时代、云计算时代、手机安卓时代、大数据时代、ICT时代、AI深度学习时代、智能机器时代,我不知道未来还会有什么时代,只记得这一路走来,充满着艰辛与收获,愿同大家一起走下去,充满希望的走下去。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/463173.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32驱动SG90舵机

STM32驱动SG90舵机 关于SG90舵机SG90转动角度与占空比的关系驱动SG90舵机代码①确定控制引脚②写代码 SG90舵机正常驱动现象总结 关于SG90舵机 SG90是一种小型伺服电机&#xff0c;通常用于模型制作和小型机械应用中: 问题答案SG90的工作电压是多少SG90的工作电压通常为3V至7.…

QT笔记——QtPropertyBrowser的使用

上一节&#xff0c;我们将了如何去配置QtPropertyBrowser 本节&#xff0c;我们将说明 如何 去 使用QtPropertyBrowser 这个属性类的一些基本知识 简单的几种用法&#xff1a; 首先&#xff1a; 我们需要创建一个Widget 提升一个类 为 QtTreePropertyBrowser .h文件 QtVariant…

git -团队开发 版本控制

文章目录 Git的概念Git的安装过程Git结构交互方式初始化本地仓库Git常用命令add和commit命令status命令log命令log命令2reset命令hard参数/mixed参数/soft参数 删除文件找回本地库删除的文件找回暂存区删除的文件 diff命令 分支操作分支冲突问题&#xff0c;如何解决冲突题 Git…

2023年的深度学习入门指南(9) - Triton

2023年的深度学习入门指南(9) - Triton 上一篇我们学习了如何用CUDA进行编程。 下面我们将介绍几种深度学习GPU编程的优化方法。 第一种我们称之为多面体编译器。我们知道&#xff0c;在传统的IR&#xff0c;比如LLVM-IR中&#xff0c;使用条件分支来编码控制流信息。这种相对…

Find My资讯|美国苹果AirTag市场大涨,助推Find My技术的发展

根据市场调查机构 Circana公布的最新统计数据&#xff0c;在苹果 AirTag 的助推下&#xff0c;美国市场物品追踪器市场快速发展。 报告称 AirTag 等物品追踪器已经成为旅行者的必备品&#xff0c;今年 1 月和 2 月期间&#xff0c;物品追踪器的销售额同比增长了 82%&#xff…

宁波博视眼科俞存院长:晒太阳会晒出白内障?是真的吗?

春意渐浓&#xff0c;人们纷纷踏出家门&#xff0c;享受暖暖的阳光。众所周知&#xff0c;适当晒太阳可以促进人体合成维生素D&#xff0c;对身体有一定的好处。 但你知道吗?太阳光中的紫外线可能会导致部分眼病的出现&#xff0c;例如&#xff1a;白内障。 晒太阳怎么会晒出白…

【数据结构初阶】第七节.树和二叉树的基本操作

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;Java初阶数据结构 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01; 文章目…

[Linux]文件系统权限与访问控制

​⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;Linux基础操作。本文主要是分享一些Linux系统常用操作&#xff0c;内容主要来源是学校作业&#xff0c;分享出来的…

Docker 安装

系列文章目录 文章目录 系列文章目录前言一、Docker 安装地址&#xff1f;二、常用命令1. 基础命令2. docker 镜像命令 三、安装步骤1.卸载原有环境2.安装对应的依赖环境和镜像地址3. 安装过慢设置镜像4. 直接安装docker CE5. 启动docker服务6. 查看docker的版本7. 配置阿里云的…

改进YOLOv8 | 主干网络篇 | YOLOv8 更换骨干网络之 SwinTransformer | 《基于位移窗口的层次化视觉变换器》

论文地址:https://arxiv.org/pdf/2103.14030.pdf 代码地址:https://github.com/microsoft/Swin-Transformer 本文介绍了一种新的视觉Transformer,称为Swin Transformer,它可以作为计算机视觉通用的骨干网络。从语言到视觉的转换中,适应Transformer所面临的挑战源于两个领…

112页智慧城市大数据综合解决方案(ppt可编辑)

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除 项目必要性分析 完善信息基础设施布局规划&#xff0c;满足区域信息化的发展要求 信息化已成为提升城市管理、促进经济发展、改善民生的重要手段合理高效的部署宽带信息基础…

亚马逊美国站纽扣电池标准

近日&#xff0c;亚马逊美国站公布要求卖家需遵守扭电池和硬币电池的新包装和警示标签规定公告。 在亚马逊销售单独的纽扣电池和硬币电池&#xff0c;则从2023年3月2日开始&#xff0c;您需要证明您的符合儿童安全包装和警告标签要求。 适用产品有;单独的纽扣电池或硬币电池&a…

FPGA基础知识 LCMXO3LF-6900C-6BG400I FPGA可编程逻辑简介

FPGA是英文Field&#xff0d;Programmable Gate Array的缩写&#xff0c;即现场可编程门阵列&#xff0c;它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路&#xff08;ASIC&#xff09;领域中的一种半定制电路而出现的&#xff0c;既解决了定…

ThinkPHP模型操作下

ThinkPHP模型操作下 前言1. 模型设置1.name(数据表除去前后缀的名字&#xff0c;默认是当前model的类名)2.table(完整的数据表名)3.pk 改变主键名称4.schema 设置模型对应数据表字段及类型5.disuse 数据表废弃字段&#xff08;数组&#xff09;6.模型的其他属性 2. 模型的主要功…

从零搭建MySQL监控平台(mysql-exporter+Prometheus+Grafana)

文章目录 一、软件安装二、 软件配置配置mysql_exporter配置prometheus配置Grafana 本文是我自己在Macbook上本地从零开始搭建一套MySQL监控平台&#xff0c;监控的也是我本机的MySQL&#xff0c;过程包括prometheus、mysql_exporter、Grafana的配置与下载。 一、软件安装 我是…

像素(物理像素dp、逻辑像素dip、物理像素 / 逻辑像素drp)

1、像素 px实际是pixel&#xff08;像素&#xff09;的缩写&#xff0c;它是图像显示的基本单元&#xff0c;既不是一个确定的物理量&#xff0c;也不是一个点或者小方块&#xff0c;而是一个抽象概念。 一个个的小格子被定义为一个单位&#xff0c;叫做 像素 &#xff0c;2像…

【Android Framework (八) 】- Service

文章目录 知识回顾启动第一个流程initZygote的流程system_serverServiceManagerBinderLauncher的启动AMS 前言源码分析1.startService2.bindService 拓展知识1:Service的两种启动方式对Service生命周期有什么影响&#xff1f;2:Service的启动流程3:Service的onStartCommand返回…

国内直接使用的ChatGTP

ChatGTP都能做一些什么事&#xff1a; 回答问题&#xff1a;我可以通过自然语言处理技术来回答用户的问题&#xff0c;提供有用的信息和解决方案。 聊天互动&#xff1a;我可以和用户聊天互动&#xff0c;倾听对话和提供支持。 搜索&#xff1a;我可以搜索互联网和已知的数据…

宠物领养系统【GUI/Swing+MySQL】(Java课设)

系统类型 Swing窗口类型Mysql数据库存储数据 使用范围 适合作为Java课设&#xff01;&#xff01;&#xff01; 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址&#xff1a;https://download.csdn.net/download/qq_50954361/87708775 更多系统资源库…

Word行距怎么设置?基础设置,必会的4个方法!

案例&#xff1a;Word行距怎么设置 【各位朋友&#xff0c;谁知道Word行距怎么设置呀&#xff1f;今天写文章时&#xff0c;感觉所有文字都挤在一起&#xff0c;非常不美观&#xff0c;想调一下行距&#xff0c;在线等一个简单的方法&#xff01;】 Word作为打工人和学生党必…