简述建设一个网站的具体步骤,网站优化的重要性,购物网站哪个最好,一键优化内存文章目录 引言工厂方法模式简介定义与用途#xff1a;实现方式#xff1a; 使用场景优势与劣势工厂模式在spring中的应用电费计算示例#xff08;简单工厂模式#xff09;改善为方法工厂模式代码地址 引言
在软件开发的世界中#xff0c;对象的创建可能是一个复杂且重复的… 文章目录 引言工厂方法模式简介定义与用途实现方式 使用场景优势与劣势工厂模式在spring中的应用电费计算示例简单工厂模式改善为方法工厂模式代码地址 引言
在软件开发的世界中对象的创建可能是一个复杂且重复的过程。为了简化这个过程设计模式中的“工厂方法”就像一个小工厂专门负责生产特定类型的对象。今天我们来深入探索这个设计模式看看它是如何让对象的创建变得简单又有趣。
工厂方法模式简介
工厂方法模式是一种创建型设计模式。 它通过使用一个工厂类来创建对象而不是直接使用 new 运算符。这使得程序可以在不知道对象确切类型的情况下生成对象的实例。
定义与用途
工厂设计模式是一种创建型设计模式广泛应用于JDK和像Spring、Struts这样的框架中。当有一个超类和多个子类并且基于输入返回其中一个子类时使用工厂设计模式是非常合适的。
实现方式
通过将类的实例化过程从客户端代码转移到工厂类从而减少客户端的复杂性。
使用场景
当类的实例化过程复杂需要依据不同的条件来创建不同的对象时。当需要解耦对象的创建和使用时。在提供一个类库并希望只暴露接口而非实现细节时。
优势与劣势
优势 提高灵活性可以在运行时选择创建哪个类的实例。 降低耦合度客户端代码与具体类的创建过程解耦。 易于扩展添加新的类不影响现有代码。劣势 增加代码复杂性可能会引入许多新类增加系统的复杂性。 维护难度当添加新类型时可能需要修改工厂类。
工厂模式在spring中的应用
Spring框架广泛地应用了工厂模式这是Spring框架中对象管理和依赖注入核心功能的基础。以下是Spring框架中使用工厂模式的几个关键地方
BeanFactory
Spring框架中最基本的容器它提供了依赖注入DI的支持。
BeanFactory 使用工厂模式来实例化应用程序中的所有bean。
它使用 getBean 方法来创建bean实例。ApplicationContext
它是 BeanFactory 的子接口提供了更高级的特性如事件传播、资源加载等。
ApplicationContext 本身也是一个大型工厂用于创建并管理应用程序中的beans以及提供对不同类型的bean的访问。FactoryBean
Spring中特殊的bean类型用于产生其他bean实例。
这种模式允许用户实现复杂的初始化逻辑并通过Spring容器进行管理。BeanDefinition
在Spring中BeanDefinition 代表了bean的配置元数据它将如何在Spring容器中创建bean的细节描述了出来。
通过这种方式Spring使用工厂模式来创建具体的bean实例。单例模式与工厂模式的结合
默认情况下Spring容器中的所有bean都是单例的这意味着每个bean都是全局唯一的并且在整个应用程序中共享。
Spring容器作为工厂管理着这些单例bean的生命周期和实例化过程。依赖注入DI
虽然DI不是工厂模式但它利用了工厂模式的概念来实现对象的创建和依赖的注入。
DI容器如 Ap plicationContext负责创建对象和管理它们的依赖关系这在本质上是一种工厂模式的应用。电费计算示例简单工厂模式
我们将创建一个名为 Plan 的抽象类以及继承该抽象类的具体类。下一步是定义一个名为 GetPlanFactory 的工厂类。 GenerateBill 类将使用 GetPlanFactory 来获取一个 Plan 对象。它将传递信息DOMESTICPLAN / COMMERCIALPLAN / INSTITUTIONALPLAN给 GetPlanFactory以获取它所需的对象类型。
步骤 1 创建抽象计划类 首先我们定义一个抽象类 Plan它包含了计算电费所必需的方法和属性。
abstract class Plan {protected double rate;abstract void getRate();public void calculateBill(int units) {System.out.println(units * rate);}
} //end of Plan class.
步骤 2 定义具体计划类 接着我们创建具体类 DomesticPlan、CommercialPlan 和 InstitutionalPlan这些类继承自 Plan 并提供了 getRate 方法的具体实现。
class DomesticPlan extends Plan {public void getRate() {rate 3.50;}
} //end of DomesticPlan class.class CommercialPlan extends Plan {public void getRate() {rate 7.50;}
} //end of CommercialPlan class.class InstitutionalPlan extends Plan {public void getRate() {rate 5.50;}
} //end of InstitutionalPlan class.步骤 3 创建工厂类 GetPlanFactory 是一个工厂类根据传入的计划类型生成相应的计划对象。
class GetPlanFactory {public Plan getPlan(String planType) {if (planType null) {return null;}if (planType.equalsIgnoreCase(DOMESTICPLAN)) {return new DomesticPlan();} else if (planType.equalsIgnoreCase(COMMERCIALPLAN)) {return new CommercialPlan();} else if (planType.equalsIgnoreCase(INSTITUTIONALPLAN)) {return new InstitutionalPlan();}return null;}
} //end of GetPlanFactory class.
步骤 4 生成账单 GenerateBill 类使用 GetPlanFactory 来获取具体的计划对象并根据使用的单位数计算电费。
class GenerateBill {public static void main(String args[]) throws IOException {GetPlanFactory planFactory new GetPlanFactory();BufferedReader br new BufferedReader(new InputStreamReader(System.in));System.out.print(Enter the name of plan for which the bill will be generated: );String planName br.readLine();System.out.print(Enter the number of units for bill will be calculated: );int units Integer.parseInt(br.readLine());Plan p planFactory.getPlan(planName);System.out.print(Bill amount for planName of units units is: );p.getRate();p.calculateBill(units);}
} //end of GenerateBill class.
以上就是一个简单的工厂模式示例代码运行代码我们可以看到 输入相应的计划就可以算出该类型下具体的电费。
改善为方法工厂模式
当新的计划类型增加时GetPlanFactory 就需要修改。这违反了开闭原则对扩展开放对修改封闭。 以上举例属于简单工厂模式接下来改为方法工厂模式。
改造步骤
创建一个抽象的工厂类或接口。为每种计划类型创建具体的工厂类继承自抽象工厂类或实现工厂接口。每个具体工厂类实现创建相应产品对象的方法。
public abstract class GetPlanFactoryPro {abstract Plan getPlan();
}class DomesticPlanFactory extends GetPlanFactoryPro {OverridePlan getPlan() {return new DomesticPlan();}
}class CommercialPlanFactory extends GetPlanFactoryPro {OverridePlan getPlan() {return new CommercialPlan();}
}class InstitutionalPlanFactory extends GetPlanFactoryPro {OverridePlan getPlan() {return new InstitutionalPlan();}
}
调用方法
public class GenerateBillPro {public static void main(String[] args) throws IOException {BufferedReader br new BufferedReader(new InputStreamReader(System.in));System.out.print(Enter the name of plan for which the bill will be generated: );String planName br.readLine();System.out.print(Enter the number of units for bill will be calculated: );int units Integer.parseInt(br.readLine());GetPlanFactoryPro factory getFactory(planName);if (factory null) {System.out.println(Invalid Plan Type);return;}Plan p factory.getPlan();System.out.print(Bill amount for planName of units units is: );p.getRate();p.calculateBill(units);}private static GetPlanFactoryPro getFactory(String planType) {if (planType.equalsIgnoreCase(DOMESTICPLAN)) {return new DomesticPlanFactory();} else if (planType.equalsIgnoreCase(COMMERCIALPLAN)) {return new CommercialPlanFactory();} else if (planType.equalsIgnoreCase(INSTITUTIONALPLAN)) {return new InstitutionalPlanFactory();}return null;}}
**灵活性和扩展性**通过使用工厂方法模式我们增加了代码的灵活性和扩展性。如果要添加新的计划类型只需增加一个新的工厂类而无需修改现有的工厂逻辑或客户端代码。 **符合开闭原则**工厂方法模式使得我们的代码更好地符合开闭原则因为现在系统可以在不修改现有代码的情况下引入新类型的Plan。
缺点 随着产品类的增加相关的工厂类也会增加可能导致系统类的数量增长。
代码地址
23种设计模式相关代码后续会逐步提交到github上方便学习欢迎指点 代码地址 https://github.com/RuofeiSun/lf-23Pattern