Java EE设计模式分为三种类型,共23种:
- 创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
- 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
- 行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。
下面简单介绍工厂模式,适配器模式和模板方法模式:
一 工厂模式
简单列一下这个模式的家族:1、静态工厂模式 2、简单工厂模式 3、工厂方法模式 4、抽象工厂模式
1、静态工厂模式
这个最常见了,项目中的辅助类,TextUtil.isEmpty等,类+静态方法。
2、简单工厂模式
下面开始谈谈卖肉夹馍,得有个店:RoujiaMoStore
package com.zhy.pattern.factory.a; public class RoujiaMoStore { /** * 根据传入类型卖不同的肉夹馍 * * @param type * @return */ public RouJiaMo sellRouJiaMo(String type) { RouJiaMo rouJiaMo = null; if (type.equals("Suan")) { rouJiaMo = new SuanRouJiaMo(); } else if (type.equals("Tian")) { rouJiaMo = new TianRouJiaMo(); } else if (type.equals("La")) { rouJiaMo = new LaRouJiaMo(); } rouJiaMo.prepare(); rouJiaMo.fire(); rouJiaMo.pack(); return rouJiaMo; } }
然后你得有各种风味的馍馍:
package com.zhy.pattern.factory.a; public abstract class RouJiaMo { protected String name; /** * 准备工作 */ public void prepare() { System.out.println("揉面-剁肉-完成准备工作"); } /** * 使用你们的专用袋-包装 */ public void pack() { System.out.println("肉夹馍-专用袋-包装"); } /** * 秘制设备-烘烤2分钟 */ public void fire() { System.out.println("肉夹馍-专用设备-烘烤"); } }
package com.zhy.pattern.factory.a; import com.zhy.pattern.factory.a.RouJiaMo; /** * 辣味肉夹馍 * @author jing */ public class LaRouJiaMo extends RouJiaMo { public LaRouJiaMo() { this.name = "辣味肉夹馍"; } }
package com.zhy.pattern.factory.a; /** * 酸味肉夹馍 * * @author jing */ public class SuanRouJiaMo extends RouJiaMo { public SuanRouJiaMo() { this.name = "酸味肉夹馍"; } }
现在这样的设计,虽然可以支持你卖肉夹馍了,但是有点问题,生产馍的种类和你的RoujiaMoStore耦合度太高了,如果增加几种风味,删除几种风味,你得一直修改sellRouJiaMo中的方法,所以我们需要做一定的修改,此时简单工厂模式就能派上用场了。
我们开始写个简单工厂,把产生馍的过程拿出来:
package com.zhy.pattern.factory.a; public class SimpleRouJiaMoFactroy { public RouJiaMo createRouJiaMo(String type) { RouJiaMo rouJiaMo = null; if (type.equals("Suan")) { rouJiaMo = new SuanRouJiaMo(); } else if (type.equals("Tian")) { rouJiaMo = new TianRouJiaMo(); } else if (type.equals("La")) { rouJiaMo = new LaRouJiaMo(); } return rouJiaMo; } }
然后以组合的方式,让Store来使用:
package com.zhy.pattern.factory.a; public class RoujiaMoStore { private SimpleRouJiaMoFactroy factroy; public RoujiaMoStore(SimpleRouJiaMoFactroy factroy) { this.factroy = factroy; } /** * 根据传入类型卖不同的肉夹馍 * * @param type * @return */ public RouJiaMo sellRouJiaMo(String type) { RouJiaMo rouJiaMo = factroy.createRouJiaMo(type); rouJiaMo.prepare(); rouJiaMo.fire(); rouJiaMo.pack(); return rouJiaMo; } }
好了,现在你随便添加什么种类的馍,删除什么种类的馍就和Store无关了,就是么~人家只负责卖馍么~ 这就是简单工厂模式,当然了,大家也都比较熟悉。
二 适配器模式 以手机充电器为例
将一个类的接口转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以相互合作。这个定义还好,说适配器的功能就是把一个接口转成另一个接口。
代码解释哈,如题目,手机充电器一般都是5V左右吧,咱天朝的家用交流电压220V,所以手机充电需要一个适配器(降压器)
首先一部手机:Mobile.java
package com.zhy.pattern.adapter; public class Mobile { /** * 充电 * @param power */ public void inputPower(V5Power power) { int provideV5Power = power.provideV5Power(); System.out.println("手机(客户端):我需要5V电压充电,现在是-->" + provideV5Power + "V"); } }
可以看出,手机依赖一个提供5V电压的接口:
package com.zhy.pattern.adapter; /** * 提供5V电压的一个接口 * @author zhy * */ public interface V5Power { public int provideV5Power(); }
然后我们拥有的是220V家用交流电:
package com.zhy.pattern.adapter; /** * 家用220V交流电 * @author zhy * */ public class V220Power { /** * 提供220V电压 * @return */ public int provideV220Power() { System.out.println("我提供220V交流电压。"); return 220 ; } }
下面我们需要一个适配器,完成220V转5V的作用:
package com.zhy.pattern.adapter; /** * 适配器,把220V电压变成5V * @author zhy * */ public class V5PowerAdapter implements V5Power { /** * 组合的方式 */ private V220Power v220Power ; public V5PowerAdapter(V220Power v220Power) { this.v220Power = v220Power ; } @Override public int provideV5Power() { int power = v220Power.provideV220Power() ; //power经过各种操作-->5 System.out.println("适配器:我悄悄的适配了电压。"); return 5 ; } }
最后测试,我们给手机冲个电:
package com.zhy.pattern.adapter; public class Test { public static void main(String[] args) { Mobile mobile = new Mobile(); V5Power v5Power = new V5PowerAdapter(new V220Power()) ; mobile.inputPower(v5Power); } }
输出:
现有类:我提供220V交流电压。
适配器:我悄悄的适配了电压。
手机(客户端):我需要5V电压充电,现在是-->5V
可以看出,我们使用一个适配器完成了把220V转化了5V然后提供给手机使用,且我们使用了组合(OO设计原则),原有的手机,以及200V电压类都不需要变化,且手机(客户端)和220V(被适配者)完全解耦。
三 模版方法模式 展现程序员的一天
定义了一个算法的骨架,而将一些步骤延迟到子类中,模版方法使得子类可以在不改变算法结构的情况下,重新定义算法的步骤。
简单看下定义,模版方法定义了一个算法的步骤,并且允许子类为一个或多个步骤提供实现。定义还算清晰,下面来个例子展示下本公司的上班情况(纯属娱乐,如有雷同,请对号入座)。简单描述一下:本公司有程序猿、测试、HR、项目经理等人,下面使用模版方法模式,记录下所有人员的上班情况:
首先来个超类,超类中定义了一个workOneDay方法,设置为作为算法的骨架:
package com.zhy.pattern.template; public abstract class Worker { protected String name; public Worker(String name) { this.name = name; } /** * 记录一天的工作 */ public final void workOneDay() { System.out.println("-----------------work start ---------------"); enterCompany(); computerOn(); work(); computerOff(); exitCompany(); System.out.println("-----------------work end ---------------"); } /** * 工作 */ public abstract void work(); /** * 关闭电脑 */ private void computerOff() { System.out.println(name + "关闭电脑"); } /** * 打开电脑 */ private void computerOn() { System.out.println(name + "打开电脑"); } /** * 进入公司 */ public void enterCompany() { System.out.println(name + "进入公司"); } /** * 离开公司 */ public void exitCompany() { System.out.println(name + "离开公司"); } }
定义了一个上班(算法)的骨架,包含以下步骤:
a、进入公司
b、打开电脑
c、上班情况
d、关闭电脑
e、离开公司
可以看到,a、b、d、e我们在超类中已经实现,子类仅实现work这个抽象方法,记录每天的上班情况。下面各类人物入场:
程序猿:
package com.zhy.pattern.template; public class ITWorker extends Worker { public ITWorker(String name) { super(name); } @Override public void work() { System.out.println(name + "写程序-测bug-fix bug"); } }
测试人员:
package com.zhy.pattern.template; public class QAWorker extends Worker { public QAWorker(String name) { super(name); } @Override public void work() { System.out.println(name + "写测试用例-提交bug-写测试用例"); } }
项目经理:
package com.zhy.pattern.template; public class ManagerWorker extends Worker { public ManagerWorker(String name) { super(name); } @Override public void work() { System.out.println(name + "打dota..."); } }
下面我们测试下:
package com.zhy.pattern.template; public class Test { public static void main(String[] args) { Worker it1 = new ITWorker("鸿洋"); it1.workOneDay(); Worker pm = new ManagerWorker("坑货"); pm.workOneDay(); } }
输出结果:
-----------------work start --------------- 鸿洋进入公司 鸿洋打开电脑 鸿洋写程序-测bug-fix bug 鸿洋关闭电脑 鸿洋离开公司 -----------------work end --------------- -----------------work start --------------- 坑货进入公司 坑货打开电脑 坑货打dota... 坑货关闭电脑 坑货离开公司 -----------------work end ---------------
原文:https://blog.csdn.net/lmj623565791/article/details/24460585