设计模式学习(四)——《大话设计模式》

设计模式学习(四)------《大话设计模式》

1.泛型

允许在编码时使用类型参数,从而使得代码更加灵活、可重用。泛型可以应用于类、接口、方法中,通过这种方式,可以编写出适用于多种数据类型的通用代码,而不是针对每种数据类型编写重复的代码。

泛型的优势

  • 类型安全:泛型提供编译时类型检查,这意味着你可以在编译阶段就捕获到类型错误,而不是在运行时。
  • 代码重用:通过使用泛型,可以写出更加通用的代码,避免了为每种数据类型编写特定代码的需要。
  • 性能提升:使用泛型可以避免在运行时进行类型转换,因为类型检查是在编译时完成的。这可以提升程序的性能。

泛型在设计模式中的应用

泛型在许多设计模式中都有应用,使得这些设计模式更加灵活和可重用。以下是一些常见设计模式中泛型的应用示例:

工厂模式(Factory Pattern):通过使用泛型,可以创建一个通用的工厂类,它能够返回任何类型的对象。这样就不需要为每种产品创建一个特定的工厂类。

单例模式(Singleton Pattern):虽然单例模式通常不直接使用泛型,但是可以通过泛型来实现一个通用的单例生成器,这样就可以为任何类创建单例实例。

观察者模式(Observer Pattern):通过使用泛型,可以定义一个通用的观察者接口和被观察者对象,使得它们可以处理多种类型的数据。

策略模式(Strategy Pattern):泛型可以使策略模式更加灵活,因为你可以定义一个接受泛型参数的策略接口,从而使得不同的策略实现可以处理不同类型的数据。

代码示例

python 复制代码
#Python 3.5 引入了 typing 模块,通过 Type Hints 增加了对泛型的支持。
from typing import TypeVar, Generic

T = TypeVar('T')

class GenericBox(Generic[T]):
    def __init__(self, content: T):
        self.content = content

    def get_content(self) -> T:
        return self.content

int_box = GenericBox[int](123)
str_box = GenericBox[str]("Hello World")

print(f"Integer Value: {int_box.get_content()}")
print(f"String Value: {str_box.get_content()}")
java 复制代码
// JDK 5 开始引入了泛型,可以在类、接口、方法中使用泛型。
public class GenericBox<T> {
    private T t;

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }

    public static void main(String[] args) {
        GenericBox<Integer> integerBox = new GenericBox<>();
        GenericBox<String> stringBox = new GenericBox<>();

        integerBox.set(10);
        stringBox.set("Hello World");

        System.out.printf("Integer Value :%d\n\n", integerBox.get());
        System.out.printf("String Value :%s\n", stringBox.get());
    }
}
c 复制代码
//通过使用 void* 指针和函数指针来间接实现类似泛型的效果
#include <stdio.h>

// 泛型交换函数
void swap(void *a, void *b, size_t size) {
    char buffer[size];
    memcpy(buffer, a, size);
    memcpy(a, b, size);
    memcpy(b, buffer, size);
}

int main() {
    int a = 5, b = 10;
    printf("Before swap: a = %d, b = %d\n", a, b);
    swap(&a, &b, sizeof(int));
    printf("After swap: a = %d, b = %d\n", a, b);
    return 0;
}

2.委托与事件

委托(Delegation)和事件(Events)是实现低耦合、高内聚的设计原则的重要手段。它们允许软件组件以松散耦合的方式相互通信,增强了代码的可维护性和可扩展性。

委托 (Delegation)

委托是一种对象设计模式,允许对象外部的某个方法代表另一个对象来执行任务。这种模式在避免继承带来的复杂性和限制时非常有用,提供了一种灵活的替代方案。

在编程实践中,委托通常意味着将一个方法作为参数传递给另一个方法。这样做的好处是可以在运行时动态地改变方法的行为。

事件 (Events)

事件是一种使对象能够通知其他对象发生了某些事情的机制。当定义的事件发生时,已注册监听该事件的对象会收到通知并执行相应操作。这是观察者模式(Observer Pattern)的一种特殊实现。

事件广泛应用于图形用户界面(GUI)编程和异步编程中,允许应用程序响应用户操作、系统消息或其他触发条件,而无需硬编码所有可能的响应逻辑。

委托与事件在不同语言中的实现

c# 复制代码
//C# 语言对委托和事件有原生支持。委托是持有一个或多个方法的类型,而事件是基于委托的一种特殊类型,用于实现事件驱动编程
public delegate void MyDelegate(string message); // 委托定义

public class Publisher {
    public event MyDelegate MyEvent; // 事件定义

    public void RaiseEvent() {
        MyEvent?.Invoke("Hello World!");
    }
}

public class Subscriber {
    public void OnMyEvent(string message) {
        Console.WriteLine(message);
    }
}

// 使用
Publisher publisher = new Publisher();
Subscriber subscriber = new Subscriber();
publisher.MyEvent += subscriber.OnMyEvent; // 事件订阅
publisher.RaiseEvent(); // 触发事件
java 复制代码
//Java 中没有原生的委托概念,但可以通过接口实现类似的功能。Java 的事件处理通常基于监听器模式,特别是在Swing等GUI框架中。
interface MyListener {
    void onEventOccurred(String message);
}

class Publisher {
    private List<MyListener> listeners = new ArrayList<>();

    public void addListener(MyListener listener) {
        listeners.add(listener);
    }

    public void raiseEvent() {
        for (MyListener listener : listeners) {
            listener.onEventOccurred("Hello World!");
        }
    }
}

class Subscriber implements MyListener {
    @Override
    public void onEventOccurred(String message) {
        System.out.println(message);
    }
}

// 使用
Publisher publisher = new Publisher();
Subscriber subscriber = new Subscriber();
publisher.addListener(subscriber); // 添加监听器
publisher.raiseEvent(); // 触发事件
python 复制代码
#Python 中没有专门的委托和事件关键字,但可以通过函数作为一等公民(first-class citizens)的特性来实现类似的功能。
#事件驱动编程可以通过回调函数和发布/订阅模式来实现。
class Publisher:
    def __init__(self):
        self.events = []

    def subscribe(self, callback):
        self.events.append(callback)

    def raise_event(self):
        for event in self.events:
            event("Hello World!")

def subscriber(event_data):
    print(event_data)

# 使用
publisher = Publisher()
publisher.subscribe(subscriber) # 订阅事件
publisher.raise_event() # 触发事件

3.初学

对软件设计模式中的类与实例、构造方法、方法重载、属性和修饰符、封装、继承、多态、重构、抽象类、集合、接口、泛型、委托与事件等知识进行了初步的学习和了解,后面再继续学习不同的软件设计模式。

相关推荐
Alice-YUE33 分钟前
【js高频八股】防抖与节流
开发语言·前端·javascript·笔记·学习·ecmascript
北山有鸟1 小时前
修改源码法和插件法
嵌入式硬件·学习
richxu202510011 小时前
嵌入式学习之路->stm32篇->(14)通用定时器(上)
stm32·单片机·嵌入式硬件·学习
qeen872 小时前
【数据结构】建堆的时间复杂度讨论与TOP-K问题
c语言·数据结构·c++·学习·
lizhihai_992 小时前
股市学习心得-六张分时保命图
大数据·人工智能·学习
nashane3 小时前
HarmonyOS 6学习:应用签名文件丢失处理与更新完全指南
学习·华为·harmonyos·harmonyos 5
@codercjw3 小时前
公差的具体标注方法(书本上/理论上标注方法)
学习
久菜盒子工作室4 小时前
时寒冰:第五次产业大转移与未来30年国运:在“双向挤压”中实现惊险一跃
人工智能·学习
Amazing_Cacao5 小时前
CFCA精品可可产区认证课程风土解析(美洲):打破风味堆叠的假象,建立时间轴上的层次展开阅读系统
学习
永远不会的CC5 小时前
浙江华昱欣实习(4月23日~ 4月19日)
后端·学习