Java程序中如何很好地运用设计模式?

金楼家Kening


1. 模式的定义

消息分为普通消息,加急消息,特急消息多种,不同的消息类型,业务功能处理是不一样的,现在要实现这样发送提示消息的功能,该如何实现呢?

如何才能既实现功能,又能灵活地扩展呢?

桥接模式的定义: 将抽象部分与它的实现部分分离,使它们都可以独立地变化。

2. UML图

Abstraction:抽象部分的接口,通常在这个对象中,要维护一个实现部分的对象引用,抽象对象里面的方法,需要调用实现部分的对象来完成。

RefinedAbstraction:扩展抽象部分的接口,通常在这些对象中,定义跟实际业务相关的方法。

Implementor:定义实现部分的接口,通常由Implementor接口提供基本的操作,Abstraction中定义的是基于这些基本操作的业务方法

concreteImplementor:真正实现Implementor接口的对象

//抽象部分就是各个消息的类型所对应的功能,而实现部分就是各种发送消息的方式/**

* 实现发送消息的统一接口

*/public interface MessageImplementor {

/**

* 发送消息

* @param message 要发送的消息内容

* @param toUser 把消息发送的目的人员

*/

public void send(String message,String toUser);

}/**

* 以站内短消息的方式发送消息

*/public class MessageSMS implements MessageImplementor{

public void send(String message, String toUser) {

System.out.println("使用站内短消息的方式,发送消息'"+message+"'给"+toUser);

}

}/**

* 以Email的方式发送消息

*/public class MessageEmail implements MessageImplementor{

public void send(String message, String toUser) {

System.out.println("使用Email的方式,发送消息'"+message+"'给"+toUser);

}

}/**

* 以手机短消息的方式发送消息

*/public class MessageMobile implements MessageImplementor{

public void send(String message, String toUser) {

System.out.println("使用手机短消息的方式,发送消息'"+message+"'给"+toUser);

}

}/**

* 抽象的消息对象

*/public abstract class AbstractMessage {

/**

* 持有一个实现部分的对象

*/

protected MessageImplementor impl; /**

* 构造方法,传入实现部分的对象

* @param impl 实现部分的对象

*/

public AbstractMessage(MessageImplementor impl){ this.impl = impl;

} /**

* 发送消息,转调实现部分的方法

* @param message 要发送的消息内容

* @param toUser 把消息发送的目的人员

*/

public void sendMessage(String message,String toUser){ this.impl.send(message, toUser);

}

}/**

* 普通消息

*/public class CommonMessage extends AbstractMessage{

public CommonMessage(MessageImplementor impl) { super(impl);

} public void sendMessage(String message, String toUser) { //对于普通消息,什么都不干,直接调用父类的方法,把消息发送出去就可以了

super.sendMessage(message, toUser);

}

}/**

* 加急消息

*/public class UrgencyMessage extends AbstractMessage{

public UrgencyMessage(MessageImplementor impl) { super(impl);

} public void sendMessage(String message, String toUser) {

message = "加急:"+message; super.sendMessage(message, toUser);

} /**

* 监控某消息的处理过程

* @param messageId 被监控的消息的编号

* @return 包含监控到的数据对象,这里示意一下,所以用了Object

*/

public Object watch(String messageId) { //获取相应的数据,组织成监控的数据对象,然后返回

return null;

}

}/**

* 特急消息

*/public class SpecialUrgencyMessage extends AbstractMessage{

public SpecialUrgencyMessage(MessageImplementor impl) { super(impl);

} public void hurry(String messageId) { //执行催促的业务,发出催促的信息

} public void sendMessage(String message, String toUser) {

message = "特急:"+message; super.sendMessage(message, toUser); //还需要增加一条待催促的信息

}

}public class Client {

public static void main(String[] args) { //创建具体的实现对象

MessageImplementor impl = new MessageSMS(); //创建一个普通消息对象

AbstractMessage m = new CommonMessage(impl);

m.sendMessage("请喝一杯茶\

java程序媛之家


一、设计模式入门:

1.设计模式是人们在面对同类型软件工程设计问题所总结出的一些有用经验。模式不是代码,而是某类问题的通用设计解决方案

2.设计模式的本质目的是使软件工程在维护性、扩展性、变化性、复杂度方面成O(N)

3.OOP是原则,设计模式是具体方法、工具

————————————————————————————————————————————

二、策略模式

从文字方面可能我们很难理解,所以我们从实际项目入手

现在假设我们有个“鸭子项目”,首先我们用OOP的角度设计这个项目,找到鸭子中共同的特性抽取在父类中并具体实现,不同的特性不实现,由子类具体实现,好下面看代码:

public abstract class Duck {

/**

* 叫声和游泳为相同的特性抽取并具体实现

*/

public void Quack() {

System.out.println("~~gaga~~");

}

public void swim() {

System.out.println("~~im swim~~");

}

/**

* 外貌为不同的特性设计为抽象的方法,有子类具体实现

*/

public abstract void display();

}

现在我们看它的子类:

public class GreenHeadDuck extends Duck {

@Override

public void display() {

System.out.println("**GreenHead**");

}

}

public class RedHeadDuck extends Duck {

@Override

public void display() {

System.out.println("**RedHead**");

}

}

现在我们可以看到使用OOP可以很好的解决目前的问题,但是我们往往是需求不断,所以我们现在又来一个新需求:添加会飞的鸭子

好办啊,我们只要在父类中添加一个新的方法:

public abstract class Duck {

/**

* 叫声和游泳为相同的特性抽取并具体实现

*/

public void Quack() {

System.out.println("~~gaga~~");

}

public void swim() {

System.out.println("~~im swim~~");

}

/**针对新需求的方法*/

public void Fly() {

System.out.println("~~im fly~~");

}

/**

* 外貌为不同的特性设计为抽象的方法,有子类具体实现

*/

public abstract void display();

}

继承的问题:对类的局部改动,尤其超类的局部改动,会影响其他部分。影响会有溢出效应

好现在我们继续用OOP的方式去解决,使其子类覆盖Fly:

public class GreenHeadDuck extends Duck {

@Override

public void display() {

System.out.println("**GreenHead**");

}

/**

* 覆盖

* */

public void Fly() {

System.out.println("~~no fly~~");

}

}

分析问题:

需要新的设计方式,应对项目的扩展性,降低复杂度:

1)分析项目变化与不变部分,提取变化部分,抽象成接口+实现;

2)鸭子哪些功能是会根据新需求变化的?叫声、飞行…

我们将变化的功能设计成接口,下面看代码:

public interface FlyBehavior {

void fly();

}

public interface QuackBehavior {

void quack();

}

来看看新的Duck类:

public abstract class Duck {

/**

* 父类定义行为出来,但是没有具体实例化

*/

FlyBehavior mFlyBehavior;

QuackBehavior mQuackBehavior;

public Duck() {

}

public void Fly() {

if (mFlyBehavior!=null) {

mFlyBehavior.fly();

}

}

public void Quack() {

if (mQuackBehavior!=null) {

mQuackBehavior.quack();

}

}

/**

* 子类可以透过两个行为的set方法去动态改变自己的具体行为

*/

public void setmFlyBehavior(FlyBehavior mFlyBehavior) {

this.mFlyBehavior = mFlyBehavior;

}

public void setmQuackBehavior(QuackBehavior mQuackBehavior) {

this.mQuackBehavior = mQuackBehavior;

}

public abstract void display();

}

在去看看子类:

public class RedHeadDuck extends Duck{

public RedHeadDuck() {

mFlyBehavior=new GoodFlyBehavior();

mQuackBehavior=new GaGaQuackBehavior();

}

@Override

public void display() {

System.out.println("redDuck");

}

}

public class GreenHeadDuck extends Duck{

public GreenHeadDuck() {

mFlyBehavior=new BadFlyBehavior();

mQuackBehavior=new GeGeQuackBehavior();

}

@Override

public void display() {

System.out.println("greenDuck");

再来看看接口实现类:

public class BadFlyBehavior implements FlyBehavior{

@Override

public void fly() {

System.out.println("bad fly");

}

}

public class GoodFlyBehavior implements FlyBehavior{

@Override

public void fly() {

System.out.println("good fly");

}

}

public class NoFlyBehavior implements FlyBehavior{

@Override

public void fly() {

System.out.println("No fly");

}

}

public class GaGaQuackBehavior implements QuackBehavior{

@Override

public void quack() {

System.out.println("gaga quack");

}

}

public class GeGeQuackBehavior implements QuackBehavior{

@Override

public void quack() {

System.out.println("gege quack");

}

}

public class NoQuackBehavior implements QuackBehavior{

@Override

public void quack() {

System.out.println("No Quack");

}

}

在父类中我们定义好FlyBehavior & QuackBehavior 两个行为接口,然后在子类构造方法中分别设定对应的具体行为

现在来测试一下:

策略模式:分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能。此模式让行为算法的变化独立于算法的使用者

—————————————————————————————————————————————

三、观察者模式:

跟之前一样,我们还是通过实际项目入手,之后,这句话我就不重复了,直接从项目开始讲解了

现在假设我们有一个需要为A公司实时提供天气的天气预报接口项目,好的,首先我们还是以OOP的方式去解决问题,首先我们创建一个天气台对象并提供相关方法假设它可以实时为A公司提供天气数据,下面看代码:

public class MeteorologicalStation {

private float pressure;

private float temperature;

private float humidity;

private ACompany company;

public MeteorologicalStation(ACompany company) {

this.company=company;

}

public float getPressure() {

return pressure;

}

public float getTemperature() {

return temperature;

}

public float getHumidity() {

return humidity;

}

/**

* 实时提供天气情况

* */

public void uploadData(float pressure,float temperature,float humidity){

company.getMeteorologicalStationData(pressure, temperature, humidity);

}

}

ACompany为A公司:

public class ACompany {

public void getMeteorologicalStationData(float pressure, float temperature, float humidity) {

System.out.println("pressure: "+pressure+\

itkeji综合


很多想要学习java的小伙伴,都不知道该从哪下手?该从哪开始学起。今天千锋小编搜集了一些关于Java学习的一些基础的基础点,希望可以帮助到正在迷茫期的你。

Java是可以写跨平台应用软件的面向对象的设计语言,是由SunMicrosystems公司于1995年推出的Java程序设计语言和Java平台(即JavaSE,JavaEE,JavaME)的总称。java技术具有卓越的通用性、高效性、平台移植性,广泛应用于个人PC、游戏控制台、科学超级计算机,同时拥有全球最大的开发者专业社群。在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。学习Java就要有方法。好的方法事半功倍。

Java学习路线加学习知识!

  一.首先要了解Java的四个相关技术:Java程序设计语言、Javaclass文件格式、Java应用编程接口、Java虚拟机。理解它们之间的区别与联系。

Java编程语言:语法。

Java文件格式:各种文件夹、文件的后缀。

Java虚拟机(JVM):处理*.class文件的解释器。

Java应用程序接口(JavaAPI)。

二.Java是分两部分的:一个是编译,一个是运行。

Javac负责的是编译的部分,当执行Javac时,会启动Java的编译器程序。对指定扩展名的.Java文件进行编译。生成了jvm可以识别的字节码文件。也就是class文件,也就是Java的运行程序。

Java:负责运行的部分.会启动jvm.加载运行时所需的类库,并对class文件进行执行.一个文件要被执行,必须要有一个执行的起始点,这个起始点就是main函数.

Java三个体系

JavaSE以前称为J2SE。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的Java应用程序。JavaSE包含了支持Java服务开发的类。

JavaEE(JavaPlatform,EnterpriseEdition)。这个版本以前称为企业版本帮助开发,可伸缩且安全的服务器端Java应用程序。JavaEE是在JavaSE的基础上构建的,它提供Web服务、管理和通信API,可以用来实现企业级的面向服务体系结构(service-orientedarchitecture,SOA)和Web2.0应用程序。

JavaME(JavaPlatform,MicroEdition)。这个版本以前称为J2ME。JavaME为在移动设备和嵌入式设备上运行的应用程序提供一个健壮且灵活的环境。

JavaME包括灵活的用户界面、健壮的安全模型、许多内置的网络协议以及对可以动态下载的连网和离线应用程序的丰富支持。基于JavaME规范的应用程序只需编写一次,就可以用于许多设备,而且可以利用每个设备的本机功能。

读完了这篇文章相信你已经对java有了一定的理解,java并不没有看起来那么好学习,对于零基础的小伙伴更需要找一个专业的老师进行指导。

从则平、破则立,千锋秉承用良心做教育的理念,依托雄厚师资为学员打造出一套又一套高端专属课程!千锋Java培训重拳出击,带领学员用实力铸就不朽传奇。欢迎每一位想学习的小伙伴前来咨询了解。


千锋教育成都


设计模式在实际工作中的运用是一个潜移默化的过程,如果为了设计模式而设计模式,可能走上过度设计的歧途,自己也会感觉很别扭。

要想用好设计模式,我有以下三点经验:

1,首先彻底理解设计模式,为什么会有这23种设计模式,都解决的什么问题?

2,学习设计模式的使用样例。在很多开源代码中都会找到典型的使用设计模式的例子

3,理解自己的业务。先别急着套用设计模式。先理解自己的代码。看看是否有些代码可以优化。

循序渐进,不要急


IT技术圈


这里有一个误区,并不是刻意的要在项目中使用设计模式,而是实际经验发现的最佳实践提炼出来是设计模式。所以在没有很多实际经验的情况下,很难切中设计模式的使用要领。


这时候可以在了解各种设计模式的前提下,多多去看实际项目包括开源项目的使用模式,才能慢慢体会到设计模式是如何付诸实践的。接着自己多写多想,就会突然发现,某些情况就是自然而然需要使用某个设计模式的最佳时机。


scottcgi


先理解,主要的是培养这种思维。


分享到:


相關文章: