UML 的工厂方法设计模式 策略设计模式 抽象工厂设计模式 观察者设计模式

UML 的工厂方法设计模式

UML 的工厂方法设计模式是一种创建型设计模式,它通过定义一个创建对象的接口,但将具体的对象创建延迟到子类中。这样可以让子类决定实例化哪个类。该模式提供了一种创建对象的灵活方式,同时也隐藏了对象的具体实现细节。

下面通过一个示例来说明工厂方法模式的应用。

假设我们正在开发一个游戏,需要创建不同类型的角色,包括战士、法师和射手。我们可以使用工厂方法模式来创建这些角色对象。

首先,定义一个抽象的角色类 Character,其中包含一个抽象的方法 attack()

public abstract class Character {public abstract void attack();
}

然后,定义具体的角色类,继承自抽象角色类,并实现 attack() 方法:

public class Warrior extends Character {@Overridepublic void attack() {System.out.println("Warrior attacks with a sword!");}
}public class Mage extends Character {@Overridepublic void attack() {System.out.println("Mage attacks with magic spells!");}
}public class Archer extends Character {@Overridepublic void attack() {System.out.println("Archer attacks with a bow and arrows!");}
}

接下来,定义一个抽象的角色工厂类 CharacterFactory,其中包含一个抽象的工厂方法 createCharacter()

public abstract class CharacterFactory {public abstract Character createCharacter();
}

然后,定义具体的角色工厂类,继承自抽象角色工厂类,并实现 createCharacter() 方法来创建具体的角色对象:

public class WarriorFactory extends CharacterFactory {@Overridepublic Character createCharacter() {return new Warrior();}
}public class MageFactory extends CharacterFactory {@Overridepublic Character createCharacter() {return new Mage();}
}public class ArcherFactory extends CharacterFactory {@Overridepublic Character createCharacter() {return new Archer();}
}

最后,客户端代码可以通过调用工厂方法来创建不同类型的角色对象:

public class Client {public static void main(String[] args) {CharacterFactory warriorFactory = new WarriorFactory();Character warrior = warriorFactory.createCharacter();warrior.attack();CharacterFactory mageFactory = new MageFactory();Character mage = mageFactory.createCharacter();mage.attack();CharacterFactory archerFactory = new ArcherFactory();Character archer = archerFactory.createCharacter();archer.attack();}
}

这样,客户端只需要通过调用工厂方法来获取角色对象,并调用其方法来进行相应的操作,而无需关心具体的角色创建细节。

UML的策略设计模式

策略设计模式是一种行为型设计模式,它定义了一系列算法或行为,将每个算法或行为封装在独立的类中,并使它们可以互相替换。通过使用策略模式,客户端可以在运行时选择不同的策略来完成相同的任务,而不需要更改客户端的代码。

策略模式通过将不同行为封装成独立的策略类,每个策略类实现一个共同的接口或抽象类。然后在客户端代码中,通过选择具体的策略对象来改变对象的行为。

下面通过一个示例来说明策略模式的应用。

假设我们正在开发一个电商平台,需要根据不同地区的运输方式计算订单的运费。我们可以使用策略模式来实现不同的运费计算策略。

首先,定义一个抽象的运费计算策略接口 ShippingStrategy

public interface ShippingStrategy {double calculate(double originalPrice);
}

然后,定义具体的运费计算策略类,实现 ShippingStrategy 接口:

public class StandardShippingStrategy implements ShippingStrategy {@Overridepublic double calculate(double originalPrice) {// 标准运输方式的运费计算逻辑return originalPrice * 0.1;}
}public class ExpressShippingStrategy implements ShippingStrategy {@Overridepublic double calculate(double originalPrice) {// 快递运输方式的运费计算逻辑return originalPrice * 0.2;}
}public class FreeShippingStrategy implements ShippingStrategy {@Overridepublic double calculate(double originalPrice) {// 免运费运输方式的运费计算逻辑return 0.0;}
}

接下来,定义一个电商订单类 Order,其中包含一个运费计算策略对象和一个计算运费的方法:

public class Order {private ShippingStrategy shippingStrategy;public Order(ShippingStrategy shippingStrategy) {this.shippingStrategy = shippingStrategy;}public double calculateShippingFee(double originalPrice) {return shippingStrategy.calculate(originalPrice);}
}

最后,在客户端代码中,根据需要选择具体的运费计算策略进行计算:

public class Client {public static void main(String[] args) {ShippingStrategy standardShippingStrategy = new StandardShippingStrategy();Order order1 = new Order(standardShippingStrategy);double fee1 = order1.calculateShippingFee(100.0);System.out.println("Standard shipping fee: " + fee1);ShippingStrategy expressShippingStrategy = new ExpressShippingStrategy();Order order2 = new Order(expressShippingStrategy);double fee2 = order2.calculateShippingFee(100.0);System.out.println("Express shipping fee: " + fee2);ShippingStrategy freeShippingStrategy = new FreeShippingStrategy();Order order3 = new Order(freeShippingStrategy);double fee3 = order3.calculateShippingFee(100.0);System.out.println("Free shipping fee: " + fee3);}
}

这样,客户端可以根据需要选择不同的运费计算策略,并通过订单对象的方法进行运费计算。

UML的抽象工厂设计模式

抽象工厂设计模式是一种创建型设计模式,它提供了一种创建一系列相关或依赖对象的接口,而无需指定具体类。它主要解决的问题是如何创建一组具有共同特征的对象。

抽象工厂模式通过引入抽象工厂接口和具体工厂实现类,以及一系列相关的产品接口和具体产品实现类,来实现对象的创建。

下面通过一个示例来说明抽象工厂模式的应用。

假设我们正在开发一个跨平台的图形界面库,需要支持 Windows 和 Mac 两个操作系统的界面风格。我们可以使用抽象工厂模式来实现不同操作系统下的界面组件的创建。

首先,定义抽象的界面组件接口 ButtonTextbox

public interface Button {void render();
}public interface Textbox {void render();
}

然后,在每个操作系统下,定义具体的界面组件实现类:

// Windows操作系统下的界面组件实现类
public class WindowsButton implements Button {@Overridepublic void render() {// Windows风格的按钮渲染逻辑System.out.println("Rendering Windows button...");}
}public class WindowsTextbox implements Textbox {@Overridepublic void render() {// Windows风格的文本框渲染逻辑System.out.println("Rendering Windows textbox...");}
}// Mac操作系统下的界面组件实现类
public class MacButton implements Button {@Overridepublic void render() {// Mac风格的按钮渲染逻辑System.out.println("Rendering Mac button...");}
}public class MacTextbox implements Textbox {@Overridepublic void render() {// Mac风格的文本框渲染逻辑System.out.println("Rendering Mac textbox...");}
}

接下来,定义抽象工厂接口 GUIFactory,其中包含创建按钮和文本框的方法:

public interface GUIFactory {Button createButton();Textbox createTextbox();
}

然后,在每个操作系统下,定义具体的工厂实现类,分别实现 GUIFactory 接口:

// Windows操作系统下的界面组件工厂
public class WindowsGUIFactory implements GUIFactory {@Overridepublic Button createButton() {return new WindowsButton();}@Overridepublic Textbox createTextbox() {return new WindowsTextbox();}
}// Mac操作系统下的界面组件工厂
public class MacGUIFactory implements GUIFactory {@Overridepublic Button createButton() {return new MacButton();}@Overridepublic Textbox createTextbox() {return new MacTextbox();}
}

最后,在客户端代码中,根据当前操作系统选择合适的工厂,并使用工厂创建界面组件:

public class Client {public static void main(String[] args) {// 根据操作系统选择合适的工厂GUIFactory factory;if (isWindows()) {factory = new WindowsGUIFactory();} else {factory = new MacGUIFactory();}// 使用工厂创建界面组件Button button = factory.createButton();Textbox textbox = factory.createTextbox();// 使用界面组件button.render();textbox.render();}private static boolean isWindows() {// 判断当前操作系统是否为Windows// ...return true;}
}

这样,通过选择合适的工厂,可以在不同的操作系统下创建对应的界面组件,并使用这些界面组件进行开发。

UML的观察者设计模式

观察者设计模式是一种行为型设计模式,它定义了对象之间的一种一对多的依赖关系,使得当一个对象状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

在观察者模式中,有两个关键角色:观察者(Observer)和被观察者(Subject)。观察者订阅被观察者,当被观察者状态发生变化时,观察者会收到通知并执行相应的操作。

下面通过一个示例来说明观察者模式的应用。

假设有一个电子商务网站,当某个商品降价时,网站上的用户应该能够自动收到相关的通知。

首先,定义观察者接口 Observer,其中包含一个更新通知的方法:

public interface Observer {void update(String message);
}

然后,定义被观察者类 Product,其中包含订阅、取消订阅和通知观察者的方法:

import java.util.ArrayList;
import java.util.List;public class Product {private List<Observer> observers = new ArrayList<>();private String name;private double price;public Product(String name, double price) {this.name = name;this.price = price;}public void attach(Observer observer) {observers.add(observer);}public void detach(Observer observer) {observers.remove(observer);}public void setPrice(double price) {if (this.price != price) {this.price = price;notifyObservers();}}private void notifyObservers() {for (Observer observer : observers) {observer.update(name + " 的价格已经改变为 " + price);}}
}

接下来,定义观察者类 User,该类实现了 Observer 接口,当收到通知时会打印相关信息:

public class User implements Observer {private String name;public User(String name) {this.name = name;}@Overridepublic void update(String message) {System.out.println(name + " 收到通知:" + message);}
}

最后,在客户端代码中,创建被观察者对象和观察者对象,并建立订阅关系:

public class Client {public static void main(String[] args) {// 创建被观察者对象Product product = new Product("手机", 2000.0);// 创建观察者对象Observer user1 = new User("张三");Observer user2 = new User("李四");// 建立订阅关系product.attach(user1);product.attach(user2);// 改变被观察者状态,触发通知

这些设计模式在软件开发中都有广泛的应用,可以提供灵活的解决方案来实现各种需求。在使用它们时需要根据实际情况选择最合适的设计模式,并根据设计原则和模式的特性来进行设计和实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/829801.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AHB传输---突发操作

突发操作 在本协议中定义了4拍、8拍和16拍的突发&#xff0c;以及未定义长度的突发和单次传输。它支持增量和包装突发&#xff1a; 增量突发访问连续位置&#xff0c;每个传输的地址是前一个地址的增量。包装突发在跨越地址边界时会包装。地址边界的计算方法是突发中拍数与传…

Android—统一依赖版本管理

依赖版本管理有多种方式 config.gradle 用于Groovy DSL&#xff0c;新建一个 config.gradle 文件&#xff0c;然后将项目中所有依赖写在里面&#xff0c;更新只需修改 config.gradle文件内容&#xff0c;作用于所有module buildSrc 可用于Kotlin DSL或Groovy DSL&#xff0c;…

MATLAB冒号表示法

MATLAB 冒号表示法 colon(:)是在MATLAB中最有用的运算符之一。它用于创建向量&#xff0c;下标数组和指定迭代。 如果要创建包含1到10的整数的行向量&#xff0c;请编写- 示例 1:10 MATLAB执行该语句并返回包含1到10的整数的行向量- ans 1 2 3 4 5 6 7 8 9 10 如果要指定一…

github Copilot的使用总结

1. 代码建议和补全 GitHub Copilot 的基本使用涉及编写代码时的实时代码建议和补全。一旦你已经安装并配置好 GitHub Copilot 插件&#xff0c;你可以在支持的编辑器&#xff08;如 Visual Studio Code&#xff09;中开始使用 Copilot。以下是一些基本的使用步骤&#xff1a; …

VBA技术资料MF146:发出多次Beep提示声

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

Pandas 2.2 中文官方教程和指南(十七)

原文&#xff1a;pandas.pydata.org/docs/ 重复标签 原文&#xff1a;pandas.pydata.org/docs/user_guide/duplicates.html Index对象不需要是唯一的&#xff1b;你可以有重复的行或列标签。这一点可能一开始会有点困惑。如果你熟悉 SQL&#xff0c;你会知道行标签类似于表上的…

TCP/IP协议族中的TCP(三):解析其关键特性与机制

⭐小白苦学IT的博客主页⭐ ⭐初学者必看&#xff1a;Linux操作系统入门⭐ ⭐代码仓库&#xff1a;Linux代码仓库⭐ ❤关注我一起讨论和学习Linux系统 前言 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是互联网协议族中至关重要的组成部…

08.OSPF的特殊区域及其特点

OSPF特殊区域 Stub 末梢区域&#xff0c;处在AS的边缘&#xff0c;只有连接其他区域的ABR&#xff0c;没有ASBR&#xff0c;没有虚连接穿越的非骨干区域 只能接收LSA1和LSA2与 LSA3&#xff0c;不能接收LSA4和LSA5区域内部路由与外部AS路由通信&#xff0c;由本区域的ABR&am…

K8S 部署和访问 Kubernetes 仪表板(Dashboard)

文章目录 部署 Dashboard UI浏览器访问登陆系统 Dashboard 是基于网页的 Kubernetes 用户界面。 你可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中&#xff0c;也可以对容器应用排错&#xff0c;还能管理集群资源。 你可以使用 Dashboard 获取运行在集群中的应用的概览…

unit4.web服务的部署及高级优化方案

搭建web服务器要求如下&#xff1a; 1.web服务器的主机ip&#xff1a;172.25.254.100 [rootserver101 桌面]# vmset.sh 100 连接已成功激活&#xff08;D-Bus 活动路径&#xff1a;/org/freedesktop/NetworkManager/ActiveConnection/3&#xff09; [rootserver101 桌面]# ifc…

Swift中TableView的编辑模式

Swift中TableView的编辑模式可以通过UITableView的属性isEditing来控制。 要将TableView设置为编辑模式&#xff0c;可以使用以下代码&#xff1a; tableView.isEditing true要退出编辑模式&#xff0c;可以使用以下代码&#xff1a; tableView.isEditing false当TableVie…

鑫海移民荣耀呈现:EB5投资移民盛宴落幕,卓越项目引领投资新潮

随着春日的暖阳渐渐铺满大地&#xff0c;我们鑫海移民集团在这个充满希望的季节里&#xff0c;举办了一场意义非凡的EB5投资移民专题活动。于2024年4月27日&#xff08;周六&#xff09;下午13:30&#xff0c;在北京渤海润泽威斯汀酒店隆重举行&#xff0c;我们与众多热情的参与…

数据结构-前缀树

前缀树 前缀树定义 前缀树&#xff08;Trie树&#xff09;&#xff0c;又称字典树、单词查找树或键树&#xff0c;是一种专门设计用于高效存储和检索字符串集合中词项的树形数据结构。其核心特性在于能够快速实现字符串的前缀匹配&#xff0c;极大减少了无谓的字符比较&#xf…

微信小程序详解

微信小程序是一种无需下载安装即可使用的应用&#xff0c;它实现了应用“触手可及”的梦想&#xff0c;用户只需扫一扫或搜索一下即可打开应用。微信小程序全面开放申请后&#xff0c;企业、政府、媒体、其他组织或个人开发者均可申请注册。 微信小程序的特点包括&#xff1a;…

基于java的商店积分管理系统的设计与实现

功能需求 从功能上可以划分为个人信息管理、商店管理、平台管理、订单管理和数据分析。后台管理系统主要服务于商户和平台管理员&#xff0c;兑换用户是属于商户平台的自有用户&#xff0c;不会被纳入到后台管理系统中来。商户用户可以对自己的积分进行管理&#xff0c;平台管…

echarts下载图片

toolbox: {show: true,//展示工具栏itemSize:20,//icon的大小iconStyle:{borderColor:"#409eff",borderWidth:"3",color:"#fff"},right:"40px",//偏移位置feature: {saveAsImage: {title: "下载图表", //鼠标滑过之后文案na…

用wps自带工具给图片做标注

在wps中&#xff0c;选中wps中的图片&#xff0c;右键选择【编辑】进入图片编辑器&#xff0c;在选项卡面板右侧选择【标注】工具&#xff0c;再选择【添加文本】工具&#xff0c;即可直接在图片上输入文字&#xff0c;标注完成后选择【覆盖原图】就完成标注任务。

【Canvas与艺术】绘制美国星条旗

注意&#xff1a; 该图位置和大小都是按照网上说明精确绘制的。 【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>使…

uniapp 阿里云点播 其他功能

详细记录 阿里云播放器 基础功能 官方文档 继 根据业务开发了其他功能 大家可以结合 上一篇 基础阿里云播放器使用 使用

C++指针的比较

指针可以用关系运算符进行比较&#xff0c;如 、< 和 > 整体的流程&#xff1a; 初始化指针ptr指向数组var的第一个元素。进入while循环&#xff0c;循环条件是ptr的地址小于或等于数组最后一个元素的地址。在循环内&#xff0c;首先打印ptr指向的地址和该地址处的值。然…