Android 策略设计模式的使用:使用设计模式,减少烂代码,让项目更好维护

目录

大家好呀~,我是前期后期,在网上冲浪的一名程序员,分享一些自己学到的知识,希望能够帮助大家节省时间

在这里插入图片描述


前言:为什么要使用设计模式

在项目开发过程中,我们会对接很多种支付:国内(微信、支付宝),海外(日本的TakeMe、UnivaPay)等等,如果我们使用的是MVVM、或者MVP架构,那么这些逻辑都会在VM层或者P层。比如:

class QrCodeFragmentVM  {
    
    

    /**
     * 微信支付宝 获取二维码
     */
    fun twoPayCode() {
    
    }

    /**
     * takeMe Pay 获取二维码
     */
    fun takeMePay(){
    
    }

    /**
     * univa Pay 获取二维码
     */
    fun univaPay(){
    
    }


    /**
     * univa Pay 查询支付结果
     */
    fun univaPayStateQuery(){
    
    }

    /**
     * takeMe Pay 查询支付结果
     */
    fun takeMePayStateQuery(){
    
    }


}

可以看到,有很多的方法,如果后面再持续增加,那么就会很混乱,各种支付方式的方法都融合在一个类里面,久了以后,你甚至都不知道univa pay的请求方法有几个,可能有两个或者三个,会导致后面代码难以维护和新增。增加越多,越棘手。

所以接下来,我们介绍一种策略设计模式,来解决这个问题,为什么要使用设计模式呢,设计模式的作用,其实就是减少烂代码,让项目可以更好维护,不过也要视情况而使用。


一、策略和工厂设计模式来解决

1.1 定义一个接口:抽取共同项

我们来直接看代码,将支付的共同项进行一个抽取,每个策略都会有发起支付和查询交易结果的方法。

/**
 * 支付 接口 策略模式
 */
interface PaymentStrategy {
    
    

    /**
     * 发起支付
     * @param price 金额   -- 使用map,因为参数有可能很多~
     */
    suspend fun pay(params: Map<String, String>):Flow<String>


    /**
     * 查询交易结果
     */
    suspend fun queryPayState(params: Map<String, String>):Flow<String>

}

这里的参数使用Map,非常的重要,因为每种支付方式,他的参数是不一样的,如果你使用String,那么就得重载很多方法,很多参数,不利于复用。


1.2 创建一个类做默认实现

下面我们要创建一个类来做默认的实现,就像前面说的,有可能有些支付,他不只是两个方法,可能他还有上传交易结果的方法,如果直接实现接口,那么就得实现一个多余方法,所以我们这里就增加一个类做默认的实现。

/**
 * 支付 接口 策略模式 提供默认实现
 */
abstract class DefultPayMentStrategy : PaymentStrategy {
    
    

    override suspend fun pay(params: Map<String, String>):Flow<String> {
    
    
        return request {
    
      }
    }

    override suspend fun queryPayState(params: Map<String, String>): Flow<String> {
    
    
        return request {
    
      }
    }


1.3 具体的实现类:比如微信支付宝类、日本TakeMepay

接下来,就是我们的重头戏,将支付服装成一个类,各自提供自己的实现。


/**
 * 微信支付宝 类
 */
class WeChatAlipayPayMent @Inject constructor() : DefultPayMentStrategy() {
    
    
    private val TAG = "WeChatAlipayPayMent"

    /**
     * 发起支付
     */
    override suspend fun pay(params: Map<String, String>)= request<String> {
    
    
       // 请求微信支付宝的二维码。
    }

	....
}

/**
 * 日本支付 类
 */
class TakeMepayPayMent @Inject constructor() : DefultPayMentStrategy() {
    
    
    private val TAG = "TakeMepayPayMent "

    /**
     * 发起支付
     */
    override suspend fun pay(params: Map<String, String>)= request<String> {
    
    
       //请求日本支付的二维码
    }

	....
}

其实,到这里就已经发现,已经解决了我们的问题,各类的支付放到自己的类里面,这样方法就不会混乱,区分开来,这样就好维护很多。


1.4 创建支付策略工厂

由于我们需要在运行时决定使用哪个策略,我们可以创建一个工厂类来管理策略的创建。

@Singleton
class PaymentService @Inject constructor(
    private val weChatAlipayPayMent: WeChatAlipayPayMent,
     private val takeMepayPayMent: TakeMepayPayMent
) {
    
    
    fun getPaymentStrategy(type: String): PaymentStrategy {
    
      
        return when (type) {
    
      
            "weChatAlipayPayMent" -> weChatAlipayPayMent//微信支付
             "TakeMepayPayMent " -> takeMepayPayMent//日本支付
            else -> throw IllegalArgumentException("Unknown payment type: $type")
        }  
    }  
}

1.5 具体的使用

可以看到有了工厂以后,我们直接提供一个字符串就会生成对应的支付,也不需要我们创建对象了。

 @Inject
    lateinit var paymentService: PaymentService

    /**
     * 微信支付宝 获取二维码
     */
    fun twoPayCode() {
    
    
        viewModelScope.launch(Dispatchers.IO) {
    
    
            val paymentStrategy = paymentService.getPaymentStrategy("weChatAlipayPayMent")
        }
    }

二、 策略设计模式的一些概念

2.1 定义

策略设计模式是一种定义一系列算法的方法,它允许在运行时选择不同的实现。这些算法完成的是相同的工作,但实现方式不同。通过将算法封装成独立的策略类,策略设计模式使得算法的变化可以独立于使用算法的客户端。

2.2 组成部分

策略设计模式通常由以下几个部分组成:

  1. 抽象策略类:定义了一个算法家族,并声明了一个抽象的算法方法,可以被具体的策略类所替换。
  2. 具体策略类:实现了抽象策略类中定义的算法,每个具体策略类都封装了一个特定的算法实现。
  3. 环境类(上下文类):持有一个抽象策略类的引用,用于调用具体的策略类中实现的算法。环境类负责在运行时选择并调用合适的策略。

2.3 优点

  1. 算法独立性:策略模式将算法与客户端分离,使得算法可以独立变化,而不会影响到客户端的代码。
  2. 可扩展性:可以方便地增加或替换算法,从而满足不同的需求。
  3. 容易维护:策略模式将算法的实现封装在单独的类中,使得代码更加清晰、易于理解和维护。

2.4 缺点

  1. 增加系统复杂性:策略模式会增加系统中类的数量,从而增加系统的复杂性。

2.5 应用场景

  1. 当需要在不同情况下使用不同的算法时。
  2. 当一个类有多种行为或算法,并且这些行为或算法可以在运行时切换时。
  3. 当需要避免使用多重条件语句或大量的if-else语句时,以提高代码的可读性和可维护性。

好了,这篇文章就介绍到这里,我是前期后期,我们 下一篇文章 见·~

猜你喜欢

转载自blog.csdn.net/qq_40853919/article/details/143434160