首页 文章 精选 留言 我的

精选列表

搜索[java],共10000篇文章
优秀的个人博客,低调大师

java设计模式之外观模式(门面模式)(结构型模式)

针对外观模式,在项目开发和实际运用中十分频繁,但是其极易理解,下面就简要介绍一下。 一、概念介绍 外观模式(Facade),他隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。这种类型的设计模式属于结构性模式。为子系统中的一组接口提供了一个统一的访问接口,这个接口使得子系统更容易被访问或者使用。 二、角色及使用场景 简单来说,该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。这个模式中,设计到3个角色。 1).门面角色:外观模式的核心。它被客户角色调用,它熟悉子系统的功能。内部根据客户角色的需求预定了几种功能的组合。 2).子系统角色:实现了子系统的功能。它对客户角色和Facade时未知的。它内部可以有系统内的相互交互,也可以由供外界调用的接口。 3).客户角色:通过调用Facede来完成要实现的功能。 使用场景: 1- 为复杂的模块或子系统提供外界访问的模块; 2- 子系统相互独立; 3- 在层析结构中,可以使用外观模式定义系统的每一层的入口。 三、实例 下面,我们就通过一个简单的例子来实现该模式。 每个Computer都有CPU、Memory、Disk。在Computer开启和关闭的时候,相应的部件也会开启和关闭,所以,使用了该外观模式后,会使用户和部件之间解耦。如: 包体的创建: 代码实现 首先是子系统类: 【代码清单--1】 1 package com.huawei.facadeDesign.children; 2 3 import org.apache.log4j.Logger; 4 5 /** 6 * cpu子系统类 7 * @author Administrator 8 * 9 */ 10 public class CPU 11 { 12 public static final Logger LOGGER = Logger.getLogger(CPU.class); 13 public void start() 14 { 15 LOGGER.info("cpu is start..."); 16 } 17 18 public void shutDown() 19 { 20 LOGGER.info("CPU is shutDown..."); 21 } 22 } 【代码清单--2】 1 package com.huawei.facadeDesign.children; 2 3 import org.apache.log4j.Logger; 4 5 /** 6 * Disk子系统类 7 * @author Administrator 8 * 9 */ 10 public class Disk 11 { 12 public static final Logger LOGGER = Logger.getLogger(Disk.class); 13 public void start() 14 { 15 LOGGER.info("Disk is start..."); 16 } 17 18 public void shutDown() 19 { 20 LOGGER.info("Disk is shutDown..."); 21 } 22 } 【代码清单--3】 1 package com.huawei.facadeDesign.children; 2 3 import org.apache.log4j.Logger; 4 5 /** 6 * Memory子系统类 7 * @author Administrator 8 * 9 */ 10 public class Memory 11 { 12 public static final Logger LOGGER = Logger.getLogger(Memory.class); 13 public void start() 14 { 15 LOGGER.info("Memory is start..."); 16 } 17 18 public void shutDown() 19 { 20 LOGGER.info("Memory is shutDown..."); 21 } 22 } 然后是,门面类Facade 【代码清单--4】 1 package com.huawei.facadeDesign.facade; 2 3 import org.apache.log4j.Logger; 4 5 import com.huawei.facadeDesign.children.CPU; 6 import com.huawei.facadeDesign.children.Disk; 7 import com.huawei.facadeDesign.children.Memory; 8 9 10 /** 11 * 门面类(核心) 12 * @author Administrator 13 * 14 */ 15 public class Computer 16 { 17 public static final Logger LOGGER = Logger.getLogger(Computer.class); 18 19 private CPU cpu; 20 private Memory memory; 21 private Disk disk; 22 public Computer() 23 { 24 cpu = new CPU(); 25 memory = new Memory(); 26 disk = new Disk(); 27 } 28 public void start() 29 { 30 LOGGER.info("Computer start begin"); 31 cpu.start(); 32 disk.start(); 33 memory.start(); 34 LOGGER.info("Computer start end"); 35 } 36 37 public void shutDown() 38 { 39 LOGGER.info("Computer shutDown begin"); 40 cpu.shutDown(); 41 disk.shutDown(); 42 memory.shutDown(); 43 LOGGER.info("Computer shutDown end..."); 44 } 45 } 最后为,客户角色。 【代码清单--5】 1 package com.huawei.facadeDesign; 2 3 import org.apache.log4j.Logger; 4 5 import com.huawei.facadeDesign.facade.Computer; 6 7 /** 8 * 客户端类 9 * @author Administrator 10 * 11 */ 12 public class Cilent { 13 public static final Logger LOGGER = Logger.getLogger(Cilent.class); 14 public static void main(String[] args) 15 { 16 Computer computer = new Computer(); 17 computer.start(); 18 LOGGER.info("================="); 19 computer.shutDown(); 20 } 21 22 } 【代码清单--6】运行结果 从上面的实例来看,有了这个Facade类,也就是Computer类,用户就不用亲自去调用子系统中的Disk,Memory、CPU类了,不需要知道系统内部的实现细节,甚至都不用知道系统内部的构成。客户端只需要跟Facade交互就可以了。 四、优点 - 松散耦合 使得客户端和子系统之间解耦,让子系统内部的模块功能更容易扩展和维护; - 简单易用 客户端根本不需要知道子系统内部的实现,或者根本不需要知道子系统内部的构成,它只需要跟Facade类交互即可。 - 更好的划分访问层次 有些方法是对系统外的,有些方法是系统内部相互交互的使用的。子系统把那些暴露给外部的功能集中到门面中,这样就可以实现客户端的使用,很好的隐藏了子系统内部的细节。 五、延伸及应用(补充) ...

优秀的个人博客,低调大师

java设计模式之原型模式-浅克隆与深克隆

《2019年阿里云双11活动拼团》:https://www.aliyun.com/1111/2019/group-buying-share【限时】1年86元,3年229元,用来建站和编程学习【附WordPress建站教程】 定义:原型模式就是用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。 ​ 在应用程序中,有些对象比较复杂,其创建过程过于复杂,而且我们又需要频繁的利用该对象,如果这个时候我们按照常规思维new该对象,那么务必会造成资源浪费,这个时候我们就希望可以利用一个已有的对象来不断对他进行复制就好了,这就是编程中的“克隆”。原型模式直接操作底层二进制流,在创建复杂对象是效率提升明显。 ​ UML类图: ​ ​ ​ 浅克隆与深克隆: ​ 浅克隆:当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制。 深克隆:除了对象本身被复制外,对象所包含的所有成员变量也将被复制。 浅克隆: public class Person implements Cloneable { private String name; private boolean gender; private Interest interest; public Person(String name, boolean gender, Interest interest) { this.name = name; this.gender = gender; this.interest = interest; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isGender() { return gender; } public void setGender(boolean gender) { this.gender = gender; } public Interest getInterest() { return interest; } public void setInterest(Interest interest) { this.interest = interest; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", gender=" + gender + ", interest=" + interest + '}'; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public static void main(String[] args) throws CloneNotSupportedException { Interest interest = new Interest("摄影"); Person gg = new Person("gg",false,interest); System.out.println(gg); Person dxy = (Person)gg.clone(); dxy.setName("dxy"); dxy.setGender(true); dxy.interest.setName("咖啡"); System.out.println(dxy); System.out.println(gg); } } class Interest{ private String name; public Interest(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Interest{" + "name='" + name + '\'' + '}'; } } 运行结果: ​` Person{name='gg', gender=false, interest=Interest{name='摄影'}} Person{name='dxy', gender=true, interest=Interest{name='咖啡'}} Person{name='gg', gender=false, interest=Interest{name='咖啡'}} ​ ​ ​ 浅克隆对于引用类型,只克隆了引用,因此两个对象的interest公共同一个内存地址,一个对象变化,会引起另一个对象响应的变化。 ​ 深克隆: ​ public class Person implements Cloneable { private String name; private boolean gender; private Interest interest; public Person(String name, boolean gender, Interest interest) { this.name = name; this.gender = gender; this.interest = interest; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isGender() { return gender; } public void setGender(boolean gender) { this.gender = gender; } public Interest getInterest() { return interest; } public void setInterest(Interest interest) { this.interest = interest; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", gender=" + gender + ", interest=" + interest + '}'; } @Override protected Object clone() throws CloneNotSupportedException { Object obj = super.clone(); //直接调用object对象的clone()方法! //添加如下代码实现深复制(deep Clone) Person person = (Person) obj; person.interest = (Interest)this.interest.clone(); //把属性也进行克隆! return obj; } public static void main(String[] args) throws CloneNotSupportedException { Interest interest = new Interest("摄影"); Person gg = new Person("gg",false,interest); System.out.println(gg); Person dxy = (Person)gg.clone(); dxy.setName("dxy"); dxy.setGender(true); dxy.interest.setName("咖啡"); System.out.println(dxy); System.out.println(gg); } } class Interest implements Cloneable { private String name; public Interest(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "Interest{" + "name='" + name + '\'' + '}'; } } 运行结果: ​ Person{name='gg', gender=false, interest=Interest{name='摄影'}} Person{name='dxy', gender=true, interest=Interest{name='咖啡'}} Person{name='gg', gender=false, interest=Interest{name='摄影'}} ​ 通过对引用类型值Interest添加clone方法,并且对Person对象的clone方法改造,实现深克隆。 ​ ​ ​ ​ 此外还可以通过序列化和反序列化的方式实现深复制。 ​ public class Person implements Serializable { private String name; private boolean gender; private Interest interest; public Person(String name, boolean gender, Interest interest) { this.name = name; this.gender = gender; this.interest = interest; } public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isGender() { return gender; } public void setGender(boolean gender) { this.gender = gender; } public Interest getInterest() { return interest; } public void setInterest(Interest interest) { this.interest = interest; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", gender=" + gender + ", interest=" + interest + '}'; } public static void main(String[] args) throws CloneNotSupportedException,ClassNotFoundException,IOException { Interest interest = new Interest("摄影"); Person gg = new Person("gg",false,interest); System.out.println(gg); //使用序列化和反序列化实现深复制 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(gg); byte[] bytes = bos.toByteArray(); ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis); Person dxy = (Person) ois.readObject(); //克隆好的对象! dxy.interest.setName("咖啡"); System.out.println(dxy); System.out.println(gg); } } class Interest implements Serializable{ private String name; public Interest(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Interest{" + "name='" + name + '\'' + '}'; } } 运行结果: ​ Person{name='gg', gender=false, interest=Interest{name='摄影'}} Person{name='gg', gender=false, interest=Interest{name='咖啡'}} Person{name='gg', gender=false, interest=Interest{name='摄影'}} ​` 优点: ​ 当创建对象的实例较为复杂的时候,使用原型模式可以简化对象的创建过程。 直接操作二进制流,可以提高实例的创建效率。 缺点: ​ 需要为每一个类配置一个克隆方法,而且该克隆方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违反了开闭原则。 在实现深克隆时需要编写较为复杂的代码,而且当对象之间存在多重签到引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。 此外clone对象时,不调用构造方法,无视构造方法的权限。 ​

优秀的个人博客,低调大师

深入理解Java虚拟机(JVM) --- 垃圾收集算法(中)

2 回收无效对象的过程 当经可达性算法筛选出失效的对象之后,并不是立即清除,而是再给对象一次重生的机会 判断是否覆盖finalize() 未覆盖该或已调用过该方法,直接释放对象内存 已覆盖该方法且还未被执行,则将finalize()扔到F-Queue队列中 执行F-Queue中的finalize() 虚拟机会以较低的优先级执行这些finalize(),不会确保所有的finalize()都会执行结束 如果finalize()中出现耗时操作,虚拟机就直接停止执行,将该对象清除 对象重生或死亡 如果在执行finalize()方法时,将this赋给了某一个引用,则该对象重生 如果没有,那么就会被垃圾收集器清除 注意:强烈不建议使用finalize()进行任何操作!如果需要释放资源,请用try-finally或者其他方式都能做得更好. 因为finalize(

优秀的个人博客,低调大师

Java高可用集群架构与微服务架构简单分析

序 可能大部分读者都在想,为什么在这以 dubbo、spring cloud 为代表的微服务时代,我要还要整理这种已经“过时”高可用集群架构? 本人工作上大部分团队都是7-15人编制的开发团队,对应的公司项目也大都是中小型项目,最大的项目 PV/UV 也就只有 10w/2w 。在这样的场景下,中小型公司一般都是创业起步没多久,大部分都需要本着“开源节流”、“以最小的成本把产出最大化”。微服务架构相比于高可用集群架构,个人理解,对于技术团队的成员编制相对要多一点,服务器部署成本相对也要高一点。 作为技术团队负责人,肯定要为企业整体成本考虑,否则要不了多久,便是讨薪大军的一员了吧。。。 一、如何选择 1、高可用集群 适用于中小型创业公司项目架构,小型技术团队快速迭代版本发布部署需求,前期低成本运行,爆发时可通过投入适量成本横向扩容服务器抗压。 特点: 前期技术开发成本低 一定的服务器扩容成本 核心团队编制及技能要求较少 项目发布部署基本无依赖,时间成本低 服务器运维成本一般 大而全的项目模块分离设计 更省更稳的技术架构选择 微服务架构强迫症不适用 2、微服务架构 适用于业务架构较大的中大型科技公司项目架构,系统可拆分多个项目单独运营,大型技术团队、平台产品规范化管理,前期投入一定的成本,可以低成本扩容指定服务的服务器抗压。 前期一定的技术开发成本 较低的服务器扩容成本 核心团队编制及技能要求较高 项目发布部署存在依赖,逐个部署,时间成本较高 服务器运维成本一般或较高 较清晰的项目模块分离设计 更潮更时尚的技术架构选择 二、高可用集群架构 1、必备服务器清单 负载均衡服务器 web项目服务器 缓存服务器 数据库服务器(主备) 注意:可能有人会问,若是小型项目单机服务,负载均衡是否就不需要?负载均衡主要工作是分发请求到源服务器,另一个作用也是为了保护源服务器,不暴露服务器真实IP,大幅度降低服务器被DDoS攻击的风险,可参考《被人DDoS攻击了,分析一下原理和防护》 一文。 2、扩展服务器清单 更多web项目服务器(集群负载) 异步服务服务器(配置中心、消息队列、job任务等) 数据库服务器(读写分离、主从复制) 文件服务器 2、架构图 三、微服务架构 1、服务器清单 dubbo / spring cloud 全家桶组件服务器 负载均衡服务器 A模块 web项目服务器 B模块 web项目服务器 C模块 web项目服务器 XXX模块 web项目服务器 缓存服务器 数据库服务器 文件服务器 异步服务服务器(配置中心、消息队列、job任务等) 2、架构图 注:图片来源 http://yun.itheima.com/open/217.html 四、总结 综上,我们对于高可用集群和微服务架构做了简单的场景和架构图分析,并不是说什么场景下一定要用什么架构,也不是说什么最潮流就用什么架构,而是根据实际成本和产出作为出发点做选择。 创业公司刚起步,资金可能也就百来万,搞微服务架构,光技术团队和服务器一个月的成本就占了公司一大头,产品还没上线,公司就已经倒闭了; 有资源的公司,动不动就能获得千万级甚至更高级别的融资,业务方向众多,若还只是用高可用架构,所有的业务模块都臃肿在一个项目里,不论是代码管理还是人员管理上,都是巨大的资源消耗。 My Blog blog.guijianpan.com 技术交流

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册