Advertisement

Java设计模式之策略模式

  •  5星
  •     浏览量: 0
  •     大小:None
  •      文件类型:PDF


简介:
策略模式是Java设计模式中的一种行为型模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以相互替换,令算法可独立于使用它的客户而变化。 策略模式是一种行为设计模式,它使你能在运行时动态地改变对象的行为。在Java编程语言中,这种模式主要用于处理同一操作的不同实现方式,并允许系统根据不同的条件选择合适的算法或行为。 策略模式的核心结构包括三个主要部分:**策略接口(Strategy Interface)**、**具体策略实现(Concrete Strategy Implementations)** 和 **策略上下文(Context)。** - 策略接口定义了一系列通用的操作。 - 具体的策略实现提供了这些操作的不同版本,每种支付方式就是一个具体的实例。 - 策略上下文负责选择和执行相应的策略。 在电商购物场景中,用户可以选择多种不同的支付方式进行结账。例如,在一个电商平台里,常见的支付选项包括支付宝、微信支付以及银联云闪付等。如果使用传统的 if-else 语句来处理不同类型的支付方式,则会导致代码变得冗长且难以维护。为解决这一问题,可以采用策略模式。 首先定义一个**策略接口 `Payment`**: ```java public interface Payment { void payment(); } ``` 接着创建多个具体的支付实现类,如支付宝、微信和银联云闪付等,并在这些具体类中重写 `payment()` 方法: ```java public class AliPayPayment implements Payment { @Override public void payment() { System.out.println(使用支付宝进行支付); } } public class WechatPayPayment implements Payment { @Override public void payment() { System.out.println(使用微信进行支付); } } public class UnionPayPayment implements Payment { @Override public void payment() { System.out.println(使用银联云闪付进行支付); } } ``` 然后,创建一个**策略上下文 `PaymentContext` 类**来管理和调用具体的支付方法: ```java public class PaymentContext { private Payment payment; public PaymentContext(Payment payment) { this.payment = payment; } public void execute() { payment.payment(); } } ``` 在实际应用中,根据用户选择的支付方式实例化相应的策略上下文对象,并调用 `execute()` 方法: ```java public static void main(String[] args) { // 使用支付宝进行支付 PaymentContext aliPay = new PaymentContext(new AliPayPayment()); aliPay.execute(); // 使用微信进行支付 PaymentContext wechatPay = new PaymentContext(new WechatPayPayment()); wechatPay.execute(); // 使用银联云闪付进行支付 PaymentContext unionPay = new PaymentContext(new UnionPayPayment()); unionPay.execute(); } ``` 进一步地,可以使用工厂模式或枚举来简化策略的选择过程。通过创建一个 `PaymentFactory` 类根据不同的支付方式名称返回相应的实现类实例。这样不仅使代码更加整洁和易于扩展新的支付方法。 总之,策略模式提供了一种灵活的方式来动态选择算法或者行为,提高了系统的可复用性和维护性。结合其他设计模式如工厂模式可以进一步增强程序的灵活性与扩展能力。

全部评论 (0)

还没有任何评论哟~
客服
客服
  • Java
    优质
    策略模式是Java设计模式中的一种行为型模式,它定义了一系列算法,并将每一个算法封装起来,使它们可以相互替换,令算法可独立于使用它的客户而变化。 策略模式是一种行为设计模式,它使你能在运行时动态地改变对象的行为。在Java编程语言中,这种模式主要用于处理同一操作的不同实现方式,并允许系统根据不同的条件选择合适的算法或行为。 策略模式的核心结构包括三个主要部分:**策略接口(Strategy Interface)**、**具体策略实现(Concrete Strategy Implementations)** 和 **策略上下文(Context)。** - 策略接口定义了一系列通用的操作。 - 具体的策略实现提供了这些操作的不同版本,每种支付方式就是一个具体的实例。 - 策略上下文负责选择和执行相应的策略。 在电商购物场景中,用户可以选择多种不同的支付方式进行结账。例如,在一个电商平台里,常见的支付选项包括支付宝、微信支付以及银联云闪付等。如果使用传统的 if-else 语句来处理不同类型的支付方式,则会导致代码变得冗长且难以维护。为解决这一问题,可以采用策略模式。 首先定义一个**策略接口 `Payment`**: ```java public interface Payment { void payment(); } ``` 接着创建多个具体的支付实现类,如支付宝、微信和银联云闪付等,并在这些具体类中重写 `payment()` 方法: ```java public class AliPayPayment implements Payment { @Override public void payment() { System.out.println(使用支付宝进行支付); } } public class WechatPayPayment implements Payment { @Override public void payment() { System.out.println(使用微信进行支付); } } public class UnionPayPayment implements Payment { @Override public void payment() { System.out.println(使用银联云闪付进行支付); } } ``` 然后,创建一个**策略上下文 `PaymentContext` 类**来管理和调用具体的支付方法: ```java public class PaymentContext { private Payment payment; public PaymentContext(Payment payment) { this.payment = payment; } public void execute() { payment.payment(); } } ``` 在实际应用中,根据用户选择的支付方式实例化相应的策略上下文对象,并调用 `execute()` 方法: ```java public static void main(String[] args) { // 使用支付宝进行支付 PaymentContext aliPay = new PaymentContext(new AliPayPayment()); aliPay.execute(); // 使用微信进行支付 PaymentContext wechatPay = new PaymentContext(new WechatPayPayment()); wechatPay.execute(); // 使用银联云闪付进行支付 PaymentContext unionPay = new PaymentContext(new UnionPayPayment()); unionPay.execute(); } ``` 进一步地,可以使用工厂模式或枚举来简化策略的选择过程。通过创建一个 `PaymentFactory` 类根据不同的支付方式名称返回相应的实现类实例。这样不仅使代码更加整洁和易于扩展新的支付方法。 总之,策略模式提供了一种灵活的方式来动态选择算法或者行为,提高了系统的可复用性和维护性。结合其他设计模式如工厂模式可以进一步增强程序的灵活性与扩展能力。
  • 行为型.md
    优质
    本文介绍了策略模式,一种行为型设计模式,解释了其定义、优点以及应用场景,并提供了具体的代码示例来帮助理解如何在实际项目中使用该模式。 设计模式是软件工程领域内为解决常见的编程问题而提出的模板解决方案。策略模式(Strategy Pattern)是一种行为型的设计模式,其主要目标是在不改变客户端代码的情况下定义并封装一系列算法,并且能够根据需要在运行时选择使用不同的算法。 策略模式主要包括以下三个角色: 1. 抽象策略角色:这是一个接口或抽象类,它规定了所有具体策略实现的公共方法。通常,在Java中这个角色由接口或者抽象类来扮演。 2. 具体策略角色:这些是实现了抽象策略定义的方法的具体实体类。每个具体的策略都是一个算法的不同表现形式。 3. 封装角色(Context):该角色持有对某个具体策略对象的引用,并提供设置或获取当前使用的具体策略方法,同时负责执行由选定策略提供的操作。 使用场景: - 当多个相似但行为不同的类存在时,可以利用策略模式来定义这些不同之处。 - 需要根据环境选择算法的不同变体。 - 算法需要访问复杂的数据结构或信息而客户端不需要知道。 - 一个对象的行为是基于其内部状态的,并且这种变化的状态可以通过改变所使用的策略来进行管理。 在类图中,通常可以看到以下元素: - Strategy:定义所有支持算法的公共接口。Context使用这个接口来调用ConcreteStrategy实现的具体方法。 - ConcreteStrategy:它实现了由抽象策略角色提供的方法,每个具体策略代表一种特定的行为或算法。 - Context:维护一个对当前使用的AbstractStrategy对象的引用,并提供执行该策略的方法。 下面是一个简单的Java代码示例: ```java // 抽象策略接口 public interface Strategy { void doSomething(); } // 具体策略实现类1 public class ConcreteStrategy1 implements Strategy { @Override public void doSomething() { System.out.println(具体策略1的运算法则); } } // 具体策略实现类2 public class ConcreteStrategy2 implements Strategy { @Override public void doSomething() { System.out.println(具体策略2的运算法则); } } // 上下文类,用于封装和管理具体的策略对象 public class Context { private Strategy strategy; // 构造函数或setter方法来设置当前使用的是哪个具体策略 public Context(Strategy strategy) { this.strategy = strategy; } // 调用由当前使用的ConcreteStrategy提供的算法 public void doAnything() { this.strategy.doSomething(); } } // 客户端代码示例,演示如何创建并使用Context来执行策略方法 public class Client { public static void main(String[] args) { Strategy strategy = new ConcreteStrategy1(); Context context = new Context(strategy); context.doAnything(); } } ``` 在实际的应用场景中,策略模式常常与工厂模式相结合以提高代码的灵活性和解耦。例如,在Spring框架里可以通过依赖注入的方式将多种实现策略接口的具体类注入到一个工厂类中,并通过该工厂类来管理和获取特定的策略实例。 以下是结合使用Spring框架的一个示例: ```java // 定义策略接口,标记为@Component注解以便于自动扫描和注册成bean @Component public interface Strategy { void doSomething(); } // 策略实现类1,同样被标注了@Component以成为Spring的bean @Component(concreteStrategy1) public class ConcreteStrategy1 implements Strategy { @Override public void doSomething() { System.out.println(具体策略1的运算法则); } } // 策略实现类2 @Component(concreteStrategy2) public class ConcreteStrategy2 implements Strategy { @Override public void doSomething() { System.out.println(具体策略2的运算法则); } } // 创建一个工厂来管理所有的ConcreteStrategy实例,通过bean id获取具体的策略对象 @Component public class StrategyFactory { // Spring会自动将所有实现该接口的类注入到这个Map中 @Autowired private Map strategyMap; public Strategy getStrategy(String name) { return this.strategyMap.get(name); } } // 示例测试代码,展示如何通过策略工厂获取具体的实例并执行其方法 @SpringBootTest class SpringbootDemoApplicationTests { @Autowired private StrategyFactory factory; @Test public void test() { // 根据名称从工厂中获取对应的ConcreteStrategy对象,并调用doSomething方法。 this.factory.getStrategy(concreteStrategy1).doSomething(); } } ``` 通过这种方式,可以大大增强代码的灵活性和可维护性。
  • (Strategy)在Java中的介绍
    优质
    简介:策略模式是Java中的一种行为型设计模式,它定义了一系列可互换的算法,并将每种算法封装起来。通过使用策略模式,可以轻松地切换不同算法实现程序功能的变化,从而提高软件的设计灵活性和扩展性。 本段落主要介绍了Java设计模式中的策略模式(Strategy模式)。作为一种对象行为型模式,策略模式定义了一系列算法,并将这些算法封装成单独的类。需要了解这一主题的朋友可以参考相关资料。
  • 练习一(单例、工厂、).zip
    优质
    本资源包含对三种经典设计模式——单例模式、工厂模式和策略模式的基础练习代码。适合初学者通过实践加深理解。 设计一个贩卖各类书籍的电子商务网站购物车系统。对于所有教材类图书实行每本一元的折扣;对连环画类图书提供每本7%的促销折扣;非教材类计算机图书享有3%的优惠;其余书没有折扣。采用策略模式、工厂模式和单子(Monad)模式进行设计,实现上述功能要求。
  • 在JavaScript中的应用示例
    优质
    本篇文章深入探讨了如何在JavaScript中运用策略模式,并通过具体实例展示了该模式的应用技巧和优势。 策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在JavaScript中,这种模式能够帮助我们更好地组织代码,提高代码的可复用性和可扩展性。jQuery中的`animate`方法就是一个典型的策略模式应用案例。该方法允许我们在执行动画时选择不同的缓动函数(如`linear`和`cubic`)。这些缓动函数可以理解为不同的策略,它们封装了不同的动画效果计算逻辑。当调用`animate`时,我们可以传入不同类型的缓动策略来改变元素的动画表现形式。这种设计使得添加新的缓动效果变得简单:只需定义一个新的函数并将其作为策略传入即可。 另一个例子是表单验证功能的应用。传统的做法可能会使用大量的`if...else`语句来处理不同的验证规则,这会增加代码维护和扩展难度。通过采用策略模式,我们可以将每个具体的验证规则(如非空、敏感词检测或字符长度限制)封装成独立的函数,并在需要时动态选择相应的策略进行执行。这样,在需求变更的情况下,例如调整字符长度限制,我们只需修改对应的验证规则函数而无需改动其他部分。 为了实现这一模式,通常我们会定义一个策略接口或者抽象类,所有具体的策略都继承自这个接口或抽象类。由于JavaScript语言的特性,可以不强制性地定义接口,但可以通过约定或函数签名来保持一致性。例如,在上述表单验证场景中,“notNull”、“maxLength”等验证规则函数都有相同的输入参数和返回值类型,这就形成了一个无形的约束条件。 在实际应用过程中,策略模式常常与工厂模式结合使用:通过创建工厂函数根据需求动态生成并返回合适的策略对象。此外,该模式还可以用于简化条件分支判断,并减少代码之间的耦合度以提高系统的灵活性。 总的来说,在JavaScript项目中运用策略模式主要有以下几个好处: 1. 封装可变的行为:将不同的算法或行为封装成独立的策略对象,使代码结构更加清晰、易于维护和扩展。 2. 动态改变对象行为:在运行时根据具体需求选择合适的策略,增加代码灵活性。 3. 减少条件分支判断:通过采用特定策略对象的方式避免了大量`if...else`语句的存在,从而降低了代码复杂度。 因此,理解和应用策略模式有助于开发者构建出更加模块化且易于管理的JavaScript项目结构,并提高软件的质量和可维护性。
  • Java及其应用场景详解
    优质
    本文深入解析了Java中的模板模式,详细介绍了其工作原理、实现方法及实际应用案例,帮助读者理解并掌握如何在项目中灵活运用该模式。 Java设计模式中的模板模式是一种非常重要的方法论,它通过抽象类定义一个逻辑框架或原型,并将不确定的部分作为抽象方法留给子类去实现。 在使用模板模式的时候,公共的结构化逻辑需要在一个抽象基类中完成,而具体细节则被封装为单独的方法。这些具体的实现由继承自该抽象基类的具体子类提供。这种设计方式分离了通用和特定部分的功能,避免了大量的重复代码,并且使程序更加简洁、易于维护与扩展。 模板模式在实际开发中有广泛的用途。例如,在建筑领域,可以利用此模式定义一种房屋的基本结构(如门、窗等),然后根据不同需求定制具体的设计方案;再比如软件工程中,也可以通过这种方式设定一个基础框架并根据项目特性进行个性化修改。 下面是一个Java实现的例子: ```java public abstract class HouseTemplate { protected String name; public HouseTemplate(String name) { this.name = name; } protected abstract void buildDoor(); protected abstract void buildWindow(); protected abstract void buildWall(); protected abstract void buildBase(); public final void buildHouse() { System.out.println(开始建造 + name); buildBase(); buildWall(); buildDoor(); buildWindow(); System.out.println(name + 建造完成); } } ``` 以及一个具体的实现: ```java public class HouseOne extends HouseTemplate { public HouseOne(String name) { super(name); } @Override protected void buildDoor() { System.out.println(this.name + 使用防盗门); } @Override protected void buildWindow() { System.out.println(this.name + 窗户朝北); } @Override protected void buildWall() { System.out.println(this.name + 墙体使用大理石); } @Override protected void buildBase() { System.out.println(this.name + 地基采用钢铁材料); } } ``` 这种模式在软件开发、游戏设计等多个领域都有应用。它帮助开发者构建出既灵活又可扩展的代码结构,从而提高效率和质量。
  • Java详解:(Template
    优质
    本文章深入浅出地讲解了Java中的模板模式(Template Pattern),通过实例分析其原理和应用方法,帮助开发者理解和利用这一设计模式优化代码结构。 本段落主要介绍了Java设计模式中的模板模式(Template模式),它定义了一个操作的算法骨架,并将某些步骤的执行延迟到其子类中实现。需要的朋友可以参考此内容。
  • 课程
    优质
    本课程专注于软件工程中的设计模式,旨在通过经典案例解析和实际项目应用,帮助学生掌握设计模式的核心理念与实践技巧。 设计模式设计模式设计模式设计模式设计模式设计模式设计模式设计模式設計模式。
  • 结构型享元.md
    优质
    本文介绍了享元(Flyweight)设计模式的概念、应用场景及其优势,通过实例讲解了如何使用享flyweight模式优化程序性能。适合对设计模式感兴趣的开发者阅读。 享元模式(Flyweight)是23种设计模式之一,属于结构型设计模式。该模式通过共享技术有效地支持大量细粒度对象的复用。其目的是为了减少创建对象的数量,以降低内存占用并提高性能。 ### 细粒度对象 享元模式主要处理的对象是有多个内部状态的细粒度对象。这些对象因体积小而创建成本较高,并且它们的状态可以被分离为共享部分和非共享部分。通过将内部状态独立出来并在不同的实例间进行共享,享元模式得以实现。 ### 使用场景 1. 大量相似对象的情况:当应用程序需要使用大量类似的对象时,例如文本编辑器中的字符对象,在这种情况下应用享元模式可以确保相同字符只创建一次并供后续复用。 2. 缓存机制:在频繁访问某个高成本计算或创建的对象的情况下,可以通过将这些对象存储到缓存中来实现。这样当再次需要使用时可以直接从缓存获取,避免重复的计算和创建操作,从而提高系统性能。 3. 连接池与资源池设计:例如数据库连接可以在多个请求间共享以减少频繁地创建及销毁连接的操作;线程也可以通过类似的机制进行管理。 ### 作用 1. 提升效率:对于那些对象生成成本较高的情况,使用缓存可以避免重复的创建过程。 2. 减少内存消耗:尽可能多地复用对象来降低系统的整体资源需求。 ### 主要角色 - Flyweight(享元接口)定义了所有具体实现类需要遵守的方法,以便外部代码可以通过它与具体的享元交互。 - ConcreteFlyweight(具体的享元对象)实现了上述的共享状态,并提供了必要的业务逻辑方法。 - FlyweightFactory(享元工厂)用于创建和管理这些飞天模式下的实例。它维护一个池来存储已存在的或者新生成的对象,以便于复用。 - UnsharedConcreteFlyweight(非共享享元对象)不需要被分享但仍然需要遵循统一的接口以处理特定业务逻辑。 ### 类图 类图展示了各种组件之间的关系:工厂创建并管理实例;而这些实例则实现了共同定义的方法来执行各自的职责。同时,它也包括了那些不参与数据共享但是依然通过相同的接口进行操作的具体对象类型。 ### 示例代码 示例中以Java语言为例介绍了如何实现享元模式: - CharFlyweight作为抽象类规定了所有字符的操作。 - Character是CharFlyweight的子类,并实现了具体的业务逻辑方法。 - CharFactory负责创建和返回实例,确保同一类型的字符不会被重复生成。 ### 实际应用 1. 缓存:在需要快速访问数据对象时使用享元模式来实现缓存机制是一个常见做法。 2. 字符串常量池:Java中的字符串是通过一个内部的字符串池进行管理以复用相同的值,这也是享元模式的一个典型例子。 3. 线程与连接资源池设计同样遵循了这种思想。 综上所述,在对象创建成本高、数量多且状态可以分离的情况下应用享元模式能够有效减少内存消耗及提高性能。它是构建高效可扩展系统的重要工具之一。
  • 创建型-原型.md
    优质
    本文介绍了设计模式中的创建型模式之一——原型模式。通过该模式可以实现对象的复制与克隆,适用于需要频繁创建大量具有相同结构的对象场景。 原型模式是创建型设计模式的一种应用方式,用于高效地重复生成对象,并确保性能最优。这种模式通过定义一个抽象接口来实现当前对象的克隆功能。 **原型模式的基本概念:** 该模式主要涉及两个角色——抽象原型类和具体原型类。前者负责声明克隆方法,而后者则提供具体的复制逻辑以实现这个接口中的规定要求。 **应用场合分析:** 当创建复杂且成本高昂的对象时(比如需要复杂的构造过程或依赖于远程服务),使用已有的实例进行浅层或深层的副本生成可以大幅提升效率和性能。此外,在构建多个对象共享同一初始状态的情况下,预先准备一个具备该状态的原型并在此基础上复制修改是较为理想的选择。 **核心角色定义:** 1. **抽象原型(Prototype):** 这是一个所有具体实现类共同遵循的基础模板或接口,其内部包含了一个用于创建副本的方法。 2. **具体原型(Concrete Prototype):** 实现了上述基础模板中的克隆方法,并提供具体的复制逻辑。不同的具体原型可能支持不同形式的复制操作。 在面向对象设计中,通过使用UML类图可以直观展示出抽象与实现之间的关系。对于原型模式而言,通常会有一个表示接口或抽象基类的核心元素(Prototype),其内部定义了克隆方法;同时也会有若干具体的子类型继承自该核心,并且各自实现了特定的复制逻辑。 **示例代码解释:** 在提供的Java语言实例中,首先设计了一个产品原型接口ProductPrototype,其中声明了一个用于创建对象副本的方法copy。然后具体实现一个名为Product的产品类来贯彻这个接口并提供相应的克隆方法实现细节;最后,在客户端代码Client内演示了如何调用这些功能以生成新的具有相同属性的实体。 在实际开发场景中,尤其是在构建大型且复杂的面向对象系统时,原型模式能显著减少创建新实例所需的资源消耗。例如在一个在线商城应用里需要频繁处理商品分类的问题上,我们可以利用一个包含所有共享配置信息的商品类别具体原型类ProductCategory,并通过克隆方法来快速生成新的具有特定属性的类别副本。 总之,当面对对象构建成本高、复制需求频发或者存在大量初始状态需共用的情况时,采用原型模式能够有效提高程序效率和性能。