简单总结一下大佬文章方方便记忆!
转载博客:23种设计模式学习导航(Java完整版)
1. 设计模式
2. 设计模式分类
2.1. 命令模式
命令模式(Command Pattern)是一种行为型设计模式,又叫动作模式或事务模式。它将请求(命令)封装成对象,使得可以用不同的请求对客户端进行参数化,具体的请求可以在运行时更改、排队或记录,它讲发出者和接收者解耦 (顺序:发出者-->命令-->接收者)
本质:封装请求
-
应用场景
餐厅点餐:在一家餐厅中,服务员充当调用者,厨师充当接收者,菜品可以作为具体命令。当顾客想点菜时,服务员会将顾客的需求封装成一个命令对象,并传递给厨师。厨师根据命令对象中的信息来完成相应的烹饪工作。这样,顾客和厨师之间不需要直接沟通,而是通过命令对象来实现点餐和烹饪的解耦。
-
点餐场景实现
- (1) 抽象命令(Command)- Command
java
public interface Command {
//点菜
void order();
//取消点菜
void cancelOrder();
}
- (2) 接收者(Receiver)- Chef
java
public class Chef {
public void cook() {
System.out.println("厨师执行点菜命令:正在烹饪菜品...");
}
public void cancelCooking() {
System.out.println("厨师执行取消命令:停止烹饪菜品!");
}
}
- (3) 具体命令(Concrete Command)- OrderCommand
java
public class OrderCommand implements Command{
// 厨师
private Chef chef;
public OrderCommand(Chef chef) {
this.chef = chef;
}
public void order() {
//与具体的烹饪者(厨师)关联,执行点菜操作
chef.cook();
}
public void cancelOrder() {
//与具体的烹饪者(厨师)关联,执行取消点菜操作
chef.cancelCooking();
}
}
- (4) 调用者(invoker)- Waitor
java
public class Waiter {
//命令对象
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void takeOrder() {
// 服务员接收到顾客的点菜请求
System.out.println("服务员接收到顾客(客户端)点菜请求!");
// 执行点菜操作
command.order();
}
public void cancelOrder() {
// 服务员收到顾客的取消点菜请求
System.out.println("服务员接收到顾客(客户端)取消点菜请求!");
// 执行取消点菜操作
command.cancelOrder();
}
}
2.1. 策略模式
策略模式:策略模式是一种行为型模式,它将对象和行为分开,将行为定义为 一个行为接口 和 具体行为的实现。策略模式最大的特点是行为的变化,行为之间可以相互替换。每个if判断都可以理解为就是一个策略。本模式使得算法可独立于使用它的用户而变化。
- 策略模式包含如下角色:
-
Strategy: 抽象策略类:策略是一个接口,该接口定义若干个算法标识,即定义了若干个抽象方法(如下图的algorithm())
-
Context: 环境类 /上下文类:上下文是依赖于接口的类(是面向策略设计的类,如下图Context类),即上下文包含用策略(接口)声明的变量(如下图的strategy成员变量)。上下文提供一个方法(如下图Context类中的的lookAlgorithm()方法),持有一个策略类的引用,最终给客户端调用。该方法委托策略变量调用具体策略所实现的策略接口中的方法(实现接口的类重写策略(接口)中的方法,来完成具体功能)
-
ConcreteStrategy: 具体策略类:具体策略是实现策略接口的类(如下图的ConcreteStrategyA类和ConcreteStrategyB类)。具体策略实现策略接口所定义的抽象方法,即给出算法标识的具体方法。(说白了就是重写策略类的方法!)作。这样,顾客和厨师之间不需要直接沟通,而是通过命令对象来实现点餐和烹饪的解耦。
-
应用场景
假设现在要设计一个贩卖各类书籍的电子商务网站的购物车系统。一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。比如,本网站可能对所有的高级会员提供每本20%的促销折扣:对中级会员提供每本10%的促销折扣;对初级会员没有折扣。
- 根据描述,折扣是根据以下的几个算法中的一个进行的:
- 算法一:对初级会员没有折扣。
- 算法二:对中级会员提供10%的促销折扣。
- 算法三:对高级会员提供20%的促销折扣。
给出一本图书,如300元,若是高级会员,则输出价格为240元。
-
场景实现
- (1) 抽象类策略(Strategy)
java
public interface MemberStrategy {
// 一个计算价格的抽象方法
//price商品的价格 n商品的个数
public double calcPrice(double price, int n);
}
- (2) 具体实现类(Concrete Strategy)
java
// 普通会员------不打折
public class PrimaryMemberStrategy implements MemberStrategy { // 实现策略
//重写策略方法具体实现功能
@Override
public double calcPrice(double price, int n) {
return price * n;
}
}
java
// 普通会员------不打折
// 中级会员 打百分之10的折扣
public class IntermediateMemberStrategy implements MemberStrategy{
@Override
public double calcPrice(double price, int n) {
double money = (price * n) - price * n * 0.1;
return money;
}
}
java
// 普通会员------不打折
// 高级会员类 20%折扣
public class AdvanceMemberStrategy implements MemberStrategy{
@Override
public double calcPrice(double price, int n) {
double money = price * n - price * n * 0.2;
return money;
}
}
- (3) 上下文累(Context )
java
/**
* 负责和具体的策略类交互
* 这样的话,具体的算法和直接的客户端调用分离了,使得算法可以独立于客户端独立的变化。
*/
// 上下文类/环境类
public class MemberContext {
// 用户折扣策略接口
private MemberStrategy memberStrategy;
// 注入构造方法
public MemberContext(MemberStrategy memberStrategy) {
this.memberStrategy = memberStrategy;
}
// 计算价格
public double qoutePrice(double goodsPrice, int n){
// 通过接口变量调用对应的具体策略
return memberStrategy.calcPrice(goodsPrice, n);
}
}
2.3. 工厂模式 (Factory)
工厂模式:工厂模式属于创建型设计模式,它用于解耦对象的创建和使用。通常情况下,我们创建对象时需要使用new操作符,但是使用new操作符创建对象会使代码具有耦合性。工厂模式通过提供一个公共的接口,使得我们可以在不暴露对象创建逻辑的情况下创建对象。
- 工厂模式分为三种类型:
- 简单工厂
- 方法工厂
- 抽象工厂
本质: 对获取对象过程的抽象。\
- 工厂模式包含如下角色:
- Factory(工厂角色)工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有实例的内部逻辑;工厂类可以直接被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法factoryMethod(),它返回一个抽象产品类Product,所有的具体产品都是抽象产品的子类。
- Product(抽象产品角色)抽象产品角色是简单工厂模式所创建的所有对象的父类,负责描述所有实例所共有的公共接口,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个工厂方法,因为所有创建的具体产品对象都是其子类对象。
- ConcreteProduct(具体产品类)具体产品角色是简单工厂模式的创建目标,所有创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现定义在抽象产品中的抽象方法 。
-
应用场景
假设现在要设计一个贩卖各类书籍的电子商务网站的购物车系统。一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。比如,本网站可能对所有的高级会员提供每本20%的促销折扣:对中级会员提供每本10%的促销折扣;对初级会员没有折扣。
- 根据描述,折扣是根据以下的几个算法中的一个进行的:
- 算法一:对初级会员没有折扣。
- 算法二:对中级会员提供10%的促销折扣。
- 算法三:对高级会员提供20%的促销折扣。
给出一本图书,如300元,若是高级会员,则输出价格为240元。
-
场景实现
- (1) 抽象产品类(Strategy)
java
/**
* @author Evan Walker
* @version 1.0
* @desc 昂焱数据: https://www.ayshuju.com
* @date 2023/04/04 13:41:41
*/
public interface Fruit {
String getColor();
}`
- (2) 实际产品类(Concrete Strategy)
java
/**
* @author Evan Walker
* @version 1.0
* @desc 昂焱数据: https://www.ayshuju.com
* @date 2023/04/04 13:41:41
*/
public class Apple implements Fruit{
@Override
public String getColor() {
return "红色";
}
}
public class Orange implements Fruit{
@Override
public String getColor() {
return "橙色";
}
}
public class Pear implements Fruit{
@Override
public String getColor() {
return "黄色";
}
}
- (3) 工厂角色( Factory )
java
/**
* @author Evan Walker
* @version 1.0
* @desc 昂焱数据: https://www.ayshuju.com
* @date 2023/04/04 13:44:44
*/
public class FruitFactory {
public Fruit createFruit(String fruitType) {
if(fruitType.equalsIgnoreCase("Apple")){
return new Apple();
} else if(fruitType.equalsIgnoreCase("Orange")) {
return new Orange();
}else if(fruitType.equalsIgnoreCase("Pear")){
return new Pear();
}
return null;
}
}
2.4. 建造者模式
建造者模式:封装一个复杂对象的构建过程,并允许按步骤构建。
- 建造着模式包含如下角色:
- 产品类(Productiom):表示被构建的复杂对象,通常包含多个组成部分,由建造者逐步构建完成。
- 抽象构建者(Builder):定义了构建复杂对象所需要的各个部分的构建方法。
- 具体构建者(ConcreteBuilder):实现各个接口,并提供各个产品类各个部分的构建方法。
- 指挥者类(Director):读者构建者的构建顺序,指挥构建者如何构建复杂对象。
-
应用场景
肯德基套餐的实现:假设套餐主要由汉堡、薯条和饮料三种组成,每个组件都有不同种类和大小,并且每个套餐的组合方式也不同。下面以肯德徳套餐为例,解释建造者模式。
- 产品类:Meal
- 抽象构建者:MealBuilder
- 具体构建者:BeefBurgerMealBuilder, ChickenMealBuilder、ShrimpMealBuilder
- 指挥者类:MealDirector
- 场景实现
- (1)象产品类: Meal
java
public class Meal {
//汉堡包
private String burger;
//薯条
private String fries;
//饮料
private String drink;
}
- (2) 抽象构建者(MealBuilder)
java
public abstract class MealBuilder {
protected Meal meal=new Meal();
//构建汉堡
public abstract void buildBurger();
//构建薯条
public abstract void buildFries();
//构建饮料
public abstract void buildDrink();
public Meal getMeal(){
return meal;
}
}
- (3) 具体构建者( BeefBurgerMealBuilder, ChickenMealBuilder、ShrimpMealBuilder)
java
public class ChickenMealBuilder extends MealBuilder{
@Override
public void buildBurger() {
meal.setBurger("鸡肉汉堡");
}
@Override
public void buildFries() {
meal.setFries("中份薯条");
}
@Override
public void buildDrink() {
meal.setDrink("大杯果汁");
}
}
public class BeefBurgerMealBuilder extends MealBuilder {
@Override
public void buildBurger() {
meal.setBurger("牛肉汉堡");
}
@Override
public void buildFries() {
meal.setFries("大份薯条");
}
@Override
public void buildDrink() {
meal.setDrink("中杯可乐");
}
}
public class ShrimpMealBuilder extends MealBuilder {
@Override
public void buildBurger() {
meal.setBurger("虾肉汉堡");
}
@Override
public void buildFries() {
meal.setFries("小份薯条");
}
@Override
public void buildDrink() {
meal.setDrink("大杯芬达");
}
}
- (4) 指导者(Director)
java
public class MealDirector {
private MealBuilder mealBuilder;
public void setMealBuilder(MealBuilder mealBuilder){
this.mealBuilder=mealBuilder;
}
public Meal getMeal(){
return mealBuilder.getMeal();
}
//制作套餐
public void constructMeal(){
mealBuilder.buildBurger();
mealBuilder.buildFries();
mealBuilder.buildDrink();
}
}
`
(5) 测试类
```java
public class TestBuilder {
@Test
void testBuilder(){
//创建指导者
MealDirector director=new MealDirector();
//执导建造牛肉套餐
director.setMealBuilder(new BeefBurgerMealBuilder());
director.constructMeal();
Meal meal = director.getMeal();
System.out.println("牛肉套餐:"+meal.toString());
//鸡肉套餐
director.setMealBuilder(new ChickenMealBuilder());
director.constructMeal();
Meal meal2 = director.getMeal();
System.out.println("鸡肉套餐:"+meal2.toString());
//虾肉套餐
director.setMealBuilder(new ShrimpMealBuilder());
director.constructMeal();
Meal meal3 = director.getMeal();
System.out.println("虾肉套餐:"+meal3.toString());
}
}