Java的设计模式怎么使用(java,编程语言)

时间:2024-05-05 19:54:38 作者 : 石家庄SEO 分类 : 编程语言
  • TAG :

设计模式是一种通过分割那些保持不变的部分和经常变化的部分,让你的代码更容易修改的方法。

不出意外的话,每个从事编程项目的人都可能会有同样的思考。特别是那些工业级别的项目,在那里通常工作着数十甚至数百名开发者;协作过程表明必须有一些标准和规则来使代码更加优雅并适应变化。这就是为什么我们有了面向对象编程(OOP)和软件框架工具。设计模式有点类似于 OOP,但它通过将变化视为自然开发过程的一部分而进一步发展。基本上,设计模式利用了一些 OOP 的思想,比如抽象和接口,但是专注于改变的过程。

当你开始开发项目时,你经常会听到这样一个术语重构,它意味着通过改变代码使它变得更优雅和可复用;这就是设计模式耀眼的地方。当你处理现有代码时(无论是由其他人构建还是你自己过去构建的),了解设计模式可以帮助你以不同的方式看待事物,你将发现问题以及改进代码的方法。

有很多种设计模式,其中单例模式、工厂模式和观察者模式三种最受欢迎,在这篇文章中我将会一一介绍它们。

单例模式:避免每次创建一个对象

单例模式singleton pattern是非常流行的设计模式,它的实现相对来说很简单,因为你只需要一个类。然而,许多开发人员争论单例设计模式的是否利大于弊,因为它缺乏明显的好处并且容易被滥用。很少有开发人员直接实现单例;相反,像 Spring Framework 和 Google Guice 等编程框架内置了单例设计模式的特性。

但是了解单例模式仍然有巨大的用处。单例模式确保一个类仅创建一次且提供了一个对它的全局访问点。

单例模式:确保仅创建一个实例且避免在同一个项目中创建多个实例。

下面这幅图展示了典型的类对象创建过程。当客户端请求创建一个对象时,构造函数会创建或者实例化一个对象并调用方法返回这个类给调用者。但是每次请求一个对象都会发生这样的情况:构造函数被调用,一个新的对象被创建并且它返回了一个独一无二的对象。我猜面向对象语言的创建者有每次都创建一个新对象的理由,但是单例过程的支持者说这是冗余的且浪费资源。

Java的设计模式怎么使用

Normal class instantiation

下面这幅图使用单例模式创建对象。这里,构造函数仅当对象首次通过调用预先设计好的getInstance()方法时才会被调用。这通常通过检查该值是否为null来完成,并且这个对象被作为私有变量保存在单例类的内部。下次getInstance()被调用时,这个类会返回第一次被创建的对象。而没有新的对象产生;它只是返回旧的那一个。

Java的设计模式怎么使用

Singleton pattern instantiation

下面这段代码展示了创建单例模式最简单的方法:

packageorg.opensource.demo.singleton;publicclassOpensourceSingleton{privatestaticOpensourceSingletonuniqueInstance;privateOpensourceSingleton(){}publicstaticOpensourceSingletongetInstance(){if(uniqueInstance==null){uniqueInstance=newOpensourceSingleton();}returnuniqueInstance;}}

在调用方,这里展示了如何调用单例类来获取对象:

OpensourcenewObject=Opensource.getInstance();

这段代码很好的验证了单例模式的思想:

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区

  2. getInstance()被调用时,它通过检查null值来检查对象是否已经被创建。

  3. 如果值为null,它会创建一个新对象并把它保存到私有域,返回这个对象给调用者。否则直接返回之前被创建的对象。

单例模式实现的主要问题是它忽略了并行进程。当多个进程使用线程同时访问资源时,这个问题就产生了。对于这种情况有对应的解决方案,它被称为双重检查锁,用于多线程安全,如下所示:

packageorg.opensource.demo.singleton;publicclassImprovedOpensourceSingleton{privatevolatilestaticImprovedOpensourceSingletonuniqueInstance;privateImprovedOpensourceSingleton(){}publicstaticImprovedOpensourceSingletongetInstance(){if(uniqueInstance==null){synchronized(ImprovedOpensourceSingleton.class){if(uniqueInstance==null){uniqueInstance=newImprovedOpensourceSingleton();}}}returnuniqueInstance;}}

再强调一下前面的观点,确保只有在你认为这是一个安全的选择时才直接实现你的单例模式。最好的方法是通过使用一个制作精良的编程框架来利用单例功能。

工厂模式:将对象创建委派给工厂类以隐藏创建逻辑

工厂模式factory pattern是另一种众所周知的设计模式,但是有一小点复杂。实现工厂模式的方法有很多,而下列的代码示例为最简单的实现方式。为了创建对象,工厂模式定义了一个接口,让它的子类去决定实例化哪一个类。

工厂模式:将对象创建委派给工厂类,因此它能隐藏创建逻辑。

下列的图片展示了最简单的工厂模式是如何实现的。

Java的设计模式怎么使用

Factory pattern

客户端请求工厂类创建类型为 x 的某个对象,而不是客户端直接调用对象创建。根据其类型,工厂模式决定要创建和返回的对象。

在下列代码示例中,OpensourceFactory是工厂类实现,它从调用者那里获取类型并根据该输入值决定要创建和返回的对象:

packageorg.opensource.demo.factory;publicclassOpensourceFactory{publicOpensourceJVMServersgetServerByVendor([String][18]name){if(name.equals("Apache")){returnnewTomcat();}elseif(name.equals("Eclipse")){returnnewJetty();}elseif(name.equals("RedHat")){returnnewWildFly();}else{returnnull;}}}

OpenSourceJVMServer是一个 100% 的抽象类(即接口类),它指示要实现的是什么,而不是怎样实现:

packageorg.opensource.demo.factory;publicinterfaceOpensourceJVMServers{publicvoidstartServer();publicvoidstopServer();public[String][18]getName();}

这是一个OpensourceJVMServers类的实现示例。当RedHat被作为类型传递给工厂类,WildFly服务器将被创建:

packageorg.opensource.demo.factory;publicclassWildFlyimplementsOpensourceJVMServers{publicvoidstartServer(){[System][19].out.println("StartingWildFlyServer...");}publicvoidstopServer(){[System][19].out.println("ShuttingDownWildFlyServer...");}public[String][18]getName(){return"WildFly";}}

观察者模式:订阅主题并获取相关更新的通知

最后是观察者模式observer pattern。像单例模式那样,很少有专业的程序员直接实现观察者模式。但是,许多消息队列和数据服务实现都借用了观察者模式的概念。观察者模式在对象之间定义了一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都将被自动地通知和更新。

观察者模式:如果有更新,那么订阅了该话题/主题的客户端将被通知。

理解观察者模式的最简单方法是想象一个邮件列表,你可以在其中订阅任何主题,无论是开源、技术、名人、烹饪还是您感兴趣的任何其他内容。每个主题维护者一个它的订阅者列表,在观察者模式中它们相当于观察者。当某一个主题更新时,它所有的订阅者(观察者)都将被通知这次改变。并且订阅者总是能取消某一个主题的订阅。

如下图所示,客户端可以订阅不同的主题并添加观察者以获得最新信息的通知。因为观察者不断的监听着这个主题,这个观察者会通知客户端任何发生的改变。

Java的设计模式怎么使用

Observer pattern

让我们来看看观察者模式的代码示例,从主题/话题类开始:

packageorg.opensource.demo.observer;publicinterfaceTopic{publicvoidaddObserver([Observer][22]observer);publicvoiddeleteObserver([Observer][22]observer);publicvoidnotifyObservers();}

这段代码描述了一个为不同的主题去实现已定义方法的接口。注意一个观察者如何被添加、移除和通知的。

这是一个主题的实现示例:

packageorg.opensource.demo.observer;importjava.util.List;importjava.util.ArrayList;publicclassConferenceimplementsTopic{privateList<Observer>listObservers;privateinttotalAttendees;privateinttotalSpeakers;private[String][18]nameEvent;publicConference(){listObservers=newArrayList<Observer>();}publicvoidaddObserver([Observer][22]observer){listObservers.add(observer);}publicvoiddeleteObserver([Observer][22]observer){inti=listObservers.indexOf(observer);if(i>=0){listObservers.remove(i);}}publicvoidnotifyObservers(){for(inti=0,nObservers=listObservers.size();i<nObservers;++i){[Observer][22]observer=listObservers.get(i);observer.update(totalAttendees,totalSpeakers,nameEvent);}}publicvoidsetConferenceDetails(inttotalAttendees,inttotalSpeakers,[String][18]nameEvent){this.totalAttendees=totalAttendees;this.totalSpeakers=totalSpeakers;this.nameEvent=nameEvent;notifyObservers();}}

这段代码定义了一个特定主题的实现。当发生改变时,这个实现调用它自己的方法。注意这将获取观察者的数量,它以列表方式存储,并且可以通知和维护观察者。

这是一个观察者类:

packageorg.opensource.demo.observer;publicinterface[Observer][22]{publicvoidupdate(inttotalAttendees,inttotalSpeakers,[String][18]nameEvent);}

这个类定义了一个接口,不同的观察者可以实现该接口以执行特定的操作。

例如,实现了该接口的观察者可以在会议上打印出与会者和发言人的数量:

packageorg.opensource.demo.observer;publicclassMonitorConferenceAttendeesimplements[Observer][22]{privateinttotalAttendees;privateinttotalSpeakers;private[String][18]nameEvent;privateTopictopic;publicMonitorConferenceAttendees(Topictopic){this.topic=topic;topic.addObserver(this);}publicvoidupdate(inttotalAttendees,inttotalSpeakers,[String][18]nameEvent){this.totalAttendees=totalAttendees;this.totalSpeakers=totalSpeakers;this.nameEvent=nameEvent;printConferenceInfo();}publicvoidprintConferenceInfo(){[System][19].out.println(this.nameEvent+"has"+totalSpeakers+"speakersand"+totalAttendees+"attendees");}}
 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:Java的设计模式怎么使用的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:怎么安装配置Docker下一篇:

4 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18