JAVA 中的设计模式(一)_设计模式(一)-程序员宅基地

JAVA 中的设计模式(一)

1.1、创建型模式(5种)

1.1.1、单列模式:在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处:
1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。
3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。
适用场景: 1.需要生成唯一序列的环境
2.需要频繁实例化然后销毁的对象。
3.创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
4.方便资源相互通信的环境
优点:1.实现了对唯一实例访问的可控
2.对于一些需要频繁创建和销毁的对象来说可以提高系统的性能。
缺点:1. 不适用于变化频繁的对象
2.滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出。
3.如果实例化的对象长时间不被利用,系统会认为该对象是垃圾而被回收,这可能会导致对象状态的丢失。
代码示例如下图
package com.pattern.Singleton;
/**

  • 单例模式
    /
    public class Singleton {
    /
    持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 /
    private static Singleton singleton = null;
    /
    私有构造方法,防止被实例化 /
    private Singleton(){
    }
    /
    静态工程方法,创建实例,在多线程的情况下可能会出现问题,所以加上同步锁synchronized /
    public synchronized static Singleton getSingleton(){
    if (singleton != null){
    return singleton;
    }else{
    return new Singleton();
    }
    }
    /
    如果该对象被用于序列化,可以保证对象在序列化前后保持一致 /
    public Object resolve(){
    return singleton;
    }
    }
    1.1.2 、原型模式:通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象。
    这种形式涉及到三个角色:
      (1)客户(Client)角色:客户类提出创建对象的请求。
      (2)抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。
      (3)具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
     个人理解:原型模式就是多态的具体实现,通过用方法重写的方式来实现父引用指向子实例
     代码示例如下
    package com.pattern.Prototype;
    /
    *
  • 抽象原型角色
    /
    public interface Prototype {
    /
    *
    • 克隆自身的方法
    • @return 一个从自身克隆出来的对象
      */
      public Object clone();
      }

package com.pattern.Prototype;
/**

  • 具体原型角色
    */
    public class ConcretePrototype1 implements Prototype {
    @Override
    public Object clone() {
    //最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
    Prototype prototype = new ConcretePrototype1();
    return prototype;
    }
    }

package com.pattern.Prototype;
/**

  • 具体原型角色
    */
    public class ConcretePrototype2 implements Prototype {
    @Override
    public Object clone() {
    //最简单的克隆,新建一个自身对象,由于没有属性就不再复制值了
    Prototype prototype = new ConcretePrototype2();
    return prototype;
    }
    }

package com.pattern.Prototype;

public class Client {
/**
*** 持有需要使用的原型接口对象
/
private Prototype prototype;
/
***
* 构造方法,传入需要使用的原型接口对象
*/
public Client(Prototype prototype){
this.prototype = prototype;
}
public void operation(Prototype prototype){
//需要创建原型接口的对象
Prototype copyprototype = (Prototype)prototype.clone();
}
}

1.1.3、工厂模式:分为三种工厂模式,简单工厂模式,工厂模式,抽象工厂模式。
1、简单工厂模式:专门定义一个类来 负责创建其他类的实例,被创建的实例通常都具有相同的父类,具有类似的行为特征,代码示例如下

//鼠标基类
class Mouse{
    
    public void sayHi(){
    };
}
//鼠标扩展类
class DellMouse extends Mouse{
    
    @Override
    public void sayHi() {
    
        System.out.println("产品:戴尔鼠标");
    }
}
class HpMouse extends Mouse{
    
    @Override
    public void sayHi() {
    
        System.out.println("产品:惠普鼠标");
    }
}
//鼠标工厂
class MouseFactory{
    
    //生产鼠标的方法,所有的鼠标都通过该方法生成
    public static Mouse createMouse(int i) {
    
        switch (i) {
    
            case 0: return new DellMouse();
            case 1: return new HpMouse();
            default: return null;
        }
    }
}
 class NormFactory {
    
    public static void main(String[] args) {
    
        Mouse hpm = MouseFactory.createMouse(1);
        Mouse dellm = MouseFactory.createMouse(0);
        hpm.sayHi();
        dellm.sayHi();
    }
}

2、工厂模式:定义一个创建对象的接口,让子类来决定实例化那个类,使一个的类的实例化延迟到子类。
个人理解:创建一个工厂的总接口,在通过不同的对象工厂去实现这个总工厂,在对应的对象工厂中覆盖总共工厂的方法,来返回对应工厂对应对象的实例。好处方便代码解耦,需要什么对象工厂直接实现总接口工厂就可以了。
3、抽象工厂模式:提供一个创建一系列相关或相互依赖对象接口,而无需指定他们具体的类。代码如下所示

class Mouse{
    
    public void sayHi(){
    };
}

class DellMouse extends Mouse {
    
    @Override
    public void sayHi() {
    
        System.out.println("产品:戴尔鼠标");
    }
}
class HpMouse extends Mouse {
    
    @Override
    public void sayHi() {
    
        System.out.println("产品:惠普鼠标");
    }
}

class KeyBoard {
    
    public void kick(){
    };
}
class HpKeyBoard extends KeyBoard {
    
    @Override
    public void kick() {
    
        System.out.println("产品:惠普键盘");
    }
}
class DellKeyBoard extends KeyBoard {
    
    @Override
    public void kick() {
    
        System.out.println("产品:戴尔键盘");
    }
}
//总的工厂接口
interface PcFactory {
    
    public Mouse createMouse() ;
    public KeyBoard createKeyBoard() ;
}
class HpFactory implements PcFactory {
    
    @Override
    public Mouse createMouse() {
    
        return new HpMouse();
    }

    @Override
    public KeyBoard createKeyBoard() {
    
        return new HpKeyBoard();
    }
}
class DellFactory implements PcFactory {
    
    @Override
    public Mouse createMouse() {
    
        return new DellMouse();
    }
    @Override
    public KeyBoard createKeyBoard() {
    
        return new DellKeyBoard();
    }
}

//当需要增加一个华硕工厂时:
class AsusMouse extends Mouse {
    
    @Override
    public void sayHi() {
    
        System.out.println("产品:华硕鼠标");
    }
}
class AsusKeyBoard extends KeyBoard {
    
    @Override
    public void kick() {
    
        System.out.println("产品:华硕键盘");
    }
}
class AsusFactory implements PcFactory {
    
    @Override
    public Mouse createMouse() {
    
        return new AsusMouse();
    }
    @Override
    public KeyBoard createKeyBoard() {
    
        return new AsusKeyBoard();
    }
}

public class NormFactory {
    
    public static void main(String[] args) {
    
        PcFactory hpFact = new HpFactory();
        Mouse hpm = hpFact.createMouse();
        KeyBoard hpkbd = hpFact.createKeyBoard();
        
        PcFactory dellFact = new DellFactory();
        Mouse dellm = dellFact.createMouse();
        KeyBoard dellkbd = dellFact.createKeyBoard();
        
        hpm.sayHi();
        dellm.sayHi();
        
        hpkbd.kick();
        dellkbd.kick();
    }
}

1.1.4、建造者模式:是将一个复杂的对象的构建与它的表示分离,使
得同样的构建过程可以创建不同的表示。创建者模式隐藏了复杂对象的创建过程,它把复杂对象的创建过程加以抽象,通过子类继承或者重载的方式,动态的创建具有复合属性的对象。
个人理解:建造者模式不需要在构造器中传对应的参数,而是你要什么参数可以直接set进去。

package com.pattern.Builder;

// 省略 getter 和 setter 方法
class Computer {
    
    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;
    public Computer(String cpu, String screen, String memory, String mainboard) {
    
        this.cpu = cpu;
        this.screen = screen;
        this.memory = memory;
        this.mainboard = mainboard;
    }
}
 class NewComputer {
    
    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;
    public NewComputer() {
    
        throw new RuntimeException();
    }
    private NewComputer(Builder builder) {
    
        cpu = builder.cpu;
        screen = builder.screen;
        memory = builder.memory;
        mainboard = builder.mainboard;
    }
    public static final class Builder {
    
        private String cpu;
        private String screen;
        private String memory;
        private String mainboard;

        public Builder() {
    }

        public Builder cpu(String val) {
    
            cpu = val;
            return this;
        }
        public Builder screen(String val) {
    
            screen = val;
            return this;
        }
        public Builder memory(String val) {
    
            memory = val;
            return this;
        }
        public Builder mainboard(String val) {
    
            mainboard = val;
            return this;
        }
        public NewComputer build() {
    
            return new  NewComputer(this);}
    }
}
 class Click {
    
    public static void main(String[] args) {
    
        // 非 Builder 模式
        Computer computer = new Computer("cpu", "screen", "memory", "mainboard");
        // Builder 模式
        NewComputer newComputer = new NewComputer.Builder()
                .cpu("cpu")
                .screen("screen")
                .memory("memory")
                .mainboard("mainboard")
                .build();
    }
}

上面的示例代码只是传入四个参数,如果参数是十四个甚至更多,builder 模式的优势将会更加明显,传递参数更加灵活,代码具有更高的可读性。
1.1.5、原始模式:原始模型模式属于对象的创建模式。通过一个原型对象来指明要创建对象的类型,然后用复制原型对象的方法来创建出更多同类型的对象,主要就是用到了clone()这个方法进行克隆。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zxy_go1/article/details/105968630

智能推荐

c# ( winform )/ javaswing 通信录管理系统源码_winform通讯录源码-程序员宅基地

文章浏览阅读48次。c#(winform)/javaswing 通信录管理系统源码此系统同时支持mysql,sqlserver,sqlite三种数据库,有javaswing窗体和C#窗体两套代码。_winform通讯录源码

sharding-datasource之JPA基于MultiTenant动态切换数据源_currenttenantidentifierresolver-程序员宅基地

文章浏览阅读1.1k次。介绍基于sharding-datasource, jpa进行分库操作, 基于AbstractDataSourceBasedMultiTenantConnectionProviderImpl, CurrentTenantIdentifierResolver动态切换数据源SaaS服务多租户介绍,每个租户的资源都是独立的,从入口到应用部署到数据,都是完全隔离的。每个租户相当于“托管”在提供服务的公司里面,公司做的其实是统一运维。好处在于,这个隔离非常彻底,基本不太会有相互影响;如果有特殊客户要求的定制化,_currenttenantidentifierresolver

Good Site-程序员宅基地

文章浏览阅读106次。[url=http://d.hatena.ne.jp/ntaku/searchdiary?word=%2A%5BAndroid%5D][Android]Androidの開発環境構築[/url][url]http://www.adakoda.com/android/000062.html[/url][url]http://www.cnmsdn.com/t/12/[/url][url]ht...

50w字+的Java技术类校招面试题汇总,HR的话扎心了_50w 面试-程序员宅基地

文章浏览阅读165次。前言刚刚过去的双十一,让“高性能”“高可用”“亿级”这3个词变成了技术热点词汇,也让很多人再次萌发成为「架构师」的想法。先问大家一个问题:你觉得把代码熟练、完成需求加上点勤奋,就能成为架构师么?如果你这么认为,那你注定只能是“码农”。从业这么多年,我见过太多普通程序员做到架构师的例子,但更多的人在听话地把需求做出来,既不考虑更优解,也不考虑技术原理,重复千篇一律的代码,以为只要代码写的好就能做「架构师」前段时间,还有哥们儿吐槽说,他们公司的架构师编程能力还不如他,伤感自己”怀才不遇“。但其实,架构师看的是_50w 面试

数据结构与算法之快速排序_数据结构快速排序-程序员宅基地

文章浏览阅读1.3w次,点赞12次,收藏25次。快速排序概念 代码实现 时间复杂度_数据结构快速排序

【路径规划】蚁群算法栅格地图路径规划及避障【含Matlab源码 2088期】_格栅地图蚁群算法-程序员宅基地

文章浏览阅读768次。蚁群算法栅格地图路径规划及避障完整的代码,方可运行;可提供运行操作视频!适合小白!_格栅地图蚁群算法

随便推点

巨杉数据库 CTO 王涛:新一代分布式数据库-程序员宅基地

文章浏览阅读944次。2019数据技术嘉年华于11月16日在京落下了帷幕。大会历时两天,来自全国各地上千名学术精英、数据库领袖人物、数据库专家、技术爱好者在这里汇聚一堂,围绕“开源 • 智能 ..._巨杉数据库 王涛

最全css居中:水平居中+垂直居中+水平/垂直居中总结_style 水平居中-程序员宅基地

文章浏览阅读285次。一.水平居中1. 行内元素<style> #father { width: 500px; height: 300px; background-color: skyblue; text-align: center; //看父级是否为块级元素,是则父级设置text-align:center //如果不是:父级先设置为块级元素,然后再居中 (即display:block ;text-alig_style 水平居中

【愚公系列】2024年02月 《网络安全应急管理与技术实践》 015-网络安全应急技术与实践(Web层-文件上传漏洞)-程序员宅基地

文章浏览阅读2.7w次,点赞8次,收藏9次。文件上传漏洞是指网站对于用户上传文件的验证过程不严格,导致攻击者可以上传恶意文件到服务器上执行任意代码或者获取敏感信息的安全漏洞。安全问题说明1. 代码执行攻击者可以上传包含恶意代码的可执行文件,通过执行这些代码来攻击服务器,例如获取敏感信息、操控服务器等。上传的可执行文件中包含恶意代码,攻击者可以通过执行该代码来实现攻击目的。2. 文件覆盖攻击者可以通过上传同名文件覆盖服务器上的原始文件,导致原始文件的内容被篡改或者删除。

从数据仓库到大数据,数据平台这25年是怎样进化的?[转]-程序员宅基地

文章浏览阅读76次。从数据仓库到大数据,数据平台这25年是怎样进化的?大数据平台 [email protected]年前 (2016-03-23)5778℃2评论从「数据仓库」一词到现在的「大数据」,中间经历了太多的知识、架构模式的演进与变革。数据平台这25年究竟是怎样进化的?让InfoQ特约老司机为你讲解。我是从2000年开始接触数据仓库,大约08年开始进入互联网行业。很多从传统企业数..._从数据仓库到大数据,数据平台这 25 年是怎样进化的

关于使用Java后台导入excel文件,读取数据后,更新数据库,并返回数据给到前端的相关问题总结_excel 导入时第一条导入后将第一条的数据返回-程序员宅基地

文章浏览阅读2.2k次。在之前的项目中,使用到了Java后台读取excel文件数据的功能点,本想着该功能点已经做过了,这一类的应该都大差不离,不过在刚结束的一个项目中,现实给我深深的上了一课,特此编写此片博客,以作记录,并给自己提个醒,Java真的是浩瀚如海呀,任何时候其实自己都是小白,懂得越多越发谨慎。Java后台读取excel文件数据该功能点一般与Java导出excel文件这个功能点配合使用。实际上此次的问题与之前的最大区别在于,之前导出excel文件时,明确知道导出的数据每一列的字段详情,导入excel文件数据时,数据格_excel 导入时第一条导入后将第一条的数据返回

一例JAVA多线程访问卡死的现象_http-nio-8181-exec-4 线程过多导致卡死-程序员宅基地

文章浏览阅读6.9k次。  最近适配摄像头,自然的就要接收、传递音频视频数据。而这些数据是非常频繁的,如果每次都新建缓冲区,一个是影响性能,另外也显得自己水平太低。怎么办?上缓存。  音频、视频当然要分开缓存。代码很类似,自然的吾就新建了一个类,  起名?Manager显然不合适,叫Worker最好。Queue、Cache都不是太适合。  数据队列LinkedBlockingDeque,缓存用Concurre..._http-nio-8181-exec-4 线程过多导致卡死

推荐文章

热门文章

相关标签