设计模式学习之适配器

说明 在前面的文章中介绍了一些关于支付相关的功能,现在转向登录,在早些时期的系统登录就是用户使用用户名与密码进行注册,注册成功后就可以进行登录了。随着时代的发展,出现很多三方的平台,它们对外提供了获取平台用户信息的功能,例如微信、qq、微博等三方登录,在接入这些三方登录时都是遵循相应的规则,老的登录的方式需要保留,对接新的登录方式还想要使用老的登录服务,这样可以使用适配器模式来实现。 适配器模式 比如我们平常使用的转接头一样,就是一种适配器的模式。它使两个不相关的物体很好的关联在一起。对于要接入的新的登录方式,首先定义新的三方登录的接口,定义要使用的三方登录方式,如下代码示例: package cn.imcompany.adapter; /** * Created by tomyli on 2018/6/22. * Github: https://github.com/peng051410 */ public interface ThirdLogin { void wechatLogin(String accessToken); void qqLogin(String accessToken); void sinaLogin(String accessToken); } 如上定义了微信、qq、微博三种登录方式,它们都是使用accessToken来进行认证,经用户同意后获取相应的用户的信息调用方使用。下面来进行具体的实现: package cn.imcompany.adapter; /** * Created by tomyli on 2018/6/22. * Github: https://github.com/peng051410 */ public class ThirdLoginAdapter implements ThirdLogin { private LoginService loginService; public ThirdLoginAdapter() { this.loginService = new LoginService(); } @Override public void wechatLogin(String accessToken) { System.out.println("微信获取用户信息"); loginService.login(accessToken, null); } @Override public void qqLogin(String accessToken) { System.out.println("qq获取用户信息"); loginService.login(accessToken, null); } @Override public void sinaLogin(String accessToken) { System.out.println("微博获取用户信息"); loginService.login(accessToken, null); } } 在上面的实现,并没有重新写登录的逻辑,除了要调用三方平台的代码,登录的功能是直接使用老的登录服务实现的。在这个实现类中引用了老的服务,然后使用其已经非常成熟的功能来完成登录的操作。这样以最少的代码达到了新的需求也使老的服务可以正常运行。免去了很多测试的功能点。这种适配器叫做对象适配器。 ...

2018-06-26 · 2 min · 217 words · tomyli

设计模式学习之模板模式

说明 在一般实现处理用户支付订单时,通常都会在一个单独的回调项目中来处理用户的支付方式回调。一般情况下,回调的处理过程都是相似的,大体的步骤就是获取参数->验证参数->验证签名->验证支付状态(可选)->订单状态为成功增加用户的充值金额。具体的过程由于不同的支付方式不同而处理的不同。这种需求可以使用模板的模板模式来实现。 模板设计模式实现 模板模式就是由一个类来声明整个处理流程的步骤,具体的实现由各个实现类来进行实现。处理的流程不变,变是就是里面具体的实现。针对上面的支付回调,可以声明一个抽象类来声明具体的流程方法,代码如下: package cn.imcompany.callback; import java.util.Map; /** * Created by tomyli on 2018/6/21. * Github: https://github.com/peng051410 */ public abstract class PayCallback { public abstract Map<String, String> getParam(); public abstract boolean checkParam(Map<String, String> param); public abstract boolean validSign(); /** * 定义了一个钩子方法来让子类控制流程实现 * @return true:强制返回,false:不强制返回 */ public boolean forceReturn() { return false; } public String doService() { Map<String, String> map = getParam(); if (!checkParam(map)) { return "param fail"; } if (!validSign()) { return "sign fail"; } if (!map.get("status").equals("success")) { if (forceReturn()) { return "order fail"; } } return "success"; } } 在上面的PayCallback类中声明了getParam(获取参数),checkParam(验证参数),validSign(验证签名),验证支付状态四个步骤,具体的支付回调类要来实现这里声明的方法即可。下面是一个微信支付的回调类的代码实现: ...

2018-06-25 · 2 min · 224 words · tomyli

设计模式学习之策略模式

说明 策略模式是设计模式中使用频率很高的模式,主要的就是实现对行为的包装,达到结果的方式有多种,使用者可以选择任何一个方式来得到想要结果,在增加新的方式时更加的方便与灵活。它是为了适应算法的灵活性而产生的。 策略模式实现 以常用的购物为例,一般情况下购物分为浏览商品,下单,支付。在支付时消费者可以选择多种不同的支付方式,如支付宝、微信、京东支付、银联支付等。在支付中流程就可以使用到策略模式,网站为用户提供了这些支付方式可供选择,用户只需要选择自己喜欢的支付方式来进行充值就可以得到商品了。在一般情况下都会定义一个抽象类来定义支付的一些行为,如金额,商品简介等信息。实现的抽象类如以下定义: package cn.imcompany.pay; /** * Created by tomyli on 2018/6/20. * Github: https://github.com/peng051410 */ public interface Payment { boolean pay(String param); } 这样就定义了支付方式的行为,剩下的就由不同的支付方式来进行实现,比如支付宝支付、微信支付,示例代码如下: package cn.imcompany.pay; /** * Created by tomyli on 2018/6/20. * Github: https://github.com/peng051410 */ public class AliPay implements Payment { @Override public boolean pay(String param) { System.out.println("AliPay"); return true; } } public class WechatPay implements Payment { @Override public boolean pay(String param) { System.out.println("WechatPay"); return true; } } 要是再增加一种支付方式则可以实现Payment接口进行实现就可以了,一般情况下会有一个维护支付方式的常量类,由它来维护可用的支付方式。这个常量类的简化代码如下: ...

2018-06-20 · 1 min · 159 words · tomyli

设计模式学习之工厂模式

说明 工厂设计模式是23种设计模式中使用频率非常高的,属于创建型模式。主要特点是实现了实体创建与使用的分离,达到了解耦的目的。工厂设计模式一般分为简单工厂、工厂方法、抽象工厂。 前提准备 4年一界世界杯即将到来,啤酒厂商又要大嫌一笔。我们先准备好要生产的啤酒实体。 package cn.imcompany; /** * Created by tomyli on 2018/5/27. * Github: https://github.com/peng051410 */ public interface Beer { String getName(); } public class JinShiBai implements Beer { @Override public String getName() { return "金士百"; } } public class QingDao implements Beer { @Override public String getName() { return "青岛"; } } public class BaiWei implements Beer { @Override public String getName() { return "百威"; } } 在上面定义三种啤酒,它们都由抽象类Beer继承而来。下面使用简单工厂来给消费者提供啤酒。 ...

2018-06-12 · 2 min · 413 words · tomyli

设计模式学习之原型模式

特点 原型设计模式就是系统中产生的每一个对象都不相同,通过原型来创建新的对象,原型模式属于创建型模式。 实现方式 一般情况可以通过对象克隆的方式来根据一个对象创建出来多个对象,每个对象在内存占用的内存地址都不一样。在JAVA中克隆又分为浅克隆与深克隆。 浅克隆 JAVA中是按值进行传递。实现克隆的方式就是实现Cloneable接口,这样就可以重写Object对象的clone方法来进行对象的克隆。代码如下: /** * Created by tomyli on 2018/5/30. * Github: https://github.com/peng051410 */ public class Apple implements Cloneable { public String name; public double weight; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } 测试代码如下: public static void main(String[] args) throws Exception { Apple apple = new Apple(); apple.name = "apple"; apple.weight = 2.23; try { Apple clone = (Apple)apple.clone(); System.out.println(clone == apple); } catch (Exception e) { e.printStackTrace(); } } 测试代码中clone与apple是两个完全不同的对象,这样就通过apple这个原型创建出来一个全新的对象。但是这里存在一个问题,现在Apple对象中只包含了值类型的成员变量,如果包含了其它对象会克隆也会成功吗?我们在Apple对象中增加一个Stone对象的集合,代码: ...

2018-06-09 · 1 min · 195 words · tomyli

设计模式学习之单例模式

特点 单例模式就是确保在系统中只在一个实例提供功能。单例有好几种写法,主要有饿汉式、懒汉式、静态方法内部类、注册式单例。 饿汉式 饿汉式单例就是在类定义时就已经将实例进行了初始化,在系统调用时可以直接返回不需要再实例化。示例代码如下: public class Hungry { private Hungry() { } private static final Hungry INSTANCE = new Hungry(); public static Hungry getInstance() { return INSTANCE; } } 饿汉式的优点是提前进行初始化,线程安全。缺点是在系统未调用的情况下占用了内存空间,是以空间换取时间的样例 懒汉式 懒汉式就是在使用才对对象实例进行初始化,达到了延迟加载的目的。示例代码如下: public class LazyOne { private LazyOne() { } private static LazyOne instance = null; public static LazyOne getInstance() { if (instance == null) { instance = new LazyOne(); } return instance; } } 懒式式优化点使用时实例化,延迟加载。缺点是存在线程安全问题 ...

2018-06-05 · 3 min · 512 words · tomyli