当前位置: 首页 > news >正文

网站建设seo基本要求自己做一个网站难不难

网站建设seo基本要求,自己做一个网站难不难,南昌seo实用技巧,网站正在建设 h5模板开发原则和设计模式一直是软件开发中的圣经, 但是这仅仅适用于中大型的项目开发, 在小型项目的开发中, 这些规则会降低你的开发效率, 使你的工程变得繁杂. 所以只有适合你的才是最好的. 设计模式六大原则1. 单一职责原则#xff08;Single Responsibility Principle#xff0… 开发原则和设计模式一直是软件开发中的圣经, 但是这仅仅适用于中大型的项目开发, 在小型项目的开发中, 这些规则会降低你的开发效率, 使你的工程变得繁杂. 所以只有适合你的才是最好的. 设计模式六大原则1. 单一职责原则Single Responsibility Principle1. 定义2. 核心思想3. 为什么要遵守单一职责原则好处坏处 4. 实际案例不遵守单一职责原则的案例遵守单一职责原则的案例 5. 如何实现单一职责原则 2. 开放封闭原则Open Closed Principle1. 定义2. 核心思想3. 为什么要遵守开放封闭原则好处坏处 4. 实际案例违反开放封闭原则的示例遵守开放封闭原则的示例 5. 如何实现开放封闭原则 3. 里氏替换原则Liskov Substitution Principle1. 定义2. 核心思想3. 为什么要遵守里氏替换原则好处坏处 4. 实际案例不遵守里氏替换原则的案例遵守里氏替换原则的案例 5. 如何实现里氏替换原则 4. 依赖倒置原则Dependency Inversion Principle1. 定义2. 核心思想3. 为什么要遵守依赖倒置原则好处坏处 4. 实际案例不遵守依赖倒置原则的案例遵守依赖倒置原则的案例 5. 如何实现依赖倒置原则 5. 接口隔离原则Interface Segregation Principle1. 定义2. 核心思想3. 为什么要遵守接口隔离原则问题如果不遵守会带来以下问题好处遵守接口隔离原则的优势 4. 实际案例不遵守接口隔离原则的设计 5. 如何实现接口隔离原则 6. 迪米特法则Law of Demeter1. 定义非正式的描述** 2. 核心思想3. 为什么要遵守迪米特法则问题如果不遵守会带来以下问题**好处遵守迪米特法则的优势** 4. 实际案例不遵守迪米特法则的设计 5. 如何实现迪米特法则 7. 合成复用原则Composite Reuse Principle1. 定义2. 核心思想3. 为什么要遵守合成复用原则问题如果过度使用继承会带来以下问题好处遵守合成复用原则的优势 4. 实际案例不遵守合成复用原则的设计遵守合成复用原则的设计 5.如何实现合成复用原则 23种设计模式创建型模式1. 单例模式Singleton Pattern1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结 2. 工厂方法模式Factory Method Pattern1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 日志记录器工厂 3. 抽象工厂模式Abstract Factory Pattern1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 跨平台UI组件 4. 建造者模式Builder Pattern1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 电脑组装 5. 原型模式详解1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 图形编辑器代码注解 6. 组合模式(Composite Pattern) ★1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 文件系统 7. 适配器模式Adapter Pattern1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 电源适配器代码注解 8. 桥接模式Bridge Pattern1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 图形绘制代码注解 9. 装饰模式Decorator Pattern★1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 文本格式化代码注解 10. 外观模式Facade Pattern★1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 文件压缩系统 11. 享元模式Flyweight Pattern1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 文本编辑器 12. 代理模式Proxy Pattern★1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 图片加载 13. 职责链模式Chain of Responsibility Pattern1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 审批系统代码注解 14. 命令模式Command Pattern1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 文本编辑器 15. 解释器模式Interpreter Pattern1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 布尔表达式解释器 16. ### 迭代器模式详解1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 图书管理系统代码注解 17. 中介者模式1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 聊天室系统代码注解 18. 备忘录模式#1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 文本编辑器代码注解 19. 观察者模式### 观察者模式详解1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 股票价格通知系统代码注解 20. 状态模式### 状态模式详解1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 订单状态系统代码注解 21. 策略模式1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 支付系统代码注解 22. 模版方法模式1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 数据导出系统代码注解 23. 访问者模式1. 定义2. 适用场景3. 结构4. 实现步骤5. 效果好处坏处 6. 总结7. 实际案例 - 文档处理系统代码注解 设计模式六大原则 1. 单一职责原则Single Responsibility Principle 1. 定义 一个类应该只有一个引起它变化的原因即一个类应该只做一件事情。 2. 核心思想 尽量使用组合尽量不要使用继承。通过将不同的职责分离到不同的类中降低类的复杂度提高代码的可维护性。 3. 为什么要遵守单一职责原则 好处 提高代码的可读性和可维护性每个类的职责单一代码更易于理解和修改。增强系统的灵活性和可扩展性职责分离后修改一个类的实现不会影响其他类。 坏处 增加类的数量可能会导致系统中类的数量增加增加管理的复杂性。可能导致过度设计在简单的系统中过度分离职责可能导致不必要的复杂性。 4. 实际案例 不遵守单一职责原则的案例 public class Employee {public void CalculatePay() { /* 计算工资 */ }public void Save() { /* 保存到数据库 */ } }在这个例子中Employee 类同时负责工资计算和数据存储违反了单一职责原则。 遵守单一职责原则的案例 public class Employee {public void CalculatePay() { /* 计算工资 */ } }public class EmployeeRepository {public void Save(Employee employee) { /* 保存到数据库 */ } }在这个例子中Employee 类只负责工资计算而 EmployeeRepository 类负责数据存储符合单一职责原则。 5. 如何实现单一职责原则 识别类的职责分析类的功能识别出不同的职责。分离职责将不同的职责分离到不同的类中。使用接口和抽象类通过接口和抽象类定义职责确保类的实现符合单一职责。重构现有代码在不影响现有功能的前提下逐步重构代码以符合单一职责原则。 2. 开放封闭原则Open Closed Principle 1. 定义 类、模块和函数应该对扩展开放对修改关闭。 2. 核心思想 通过抽象类和接口来实现扩展而不是通过修改现有代码。 3. 为什么要遵守开放封闭原则 好处 提高系统的稳定性通过扩展而不是修改来实现新功能减少了引入新错误的风险。增强系统的可扩展性可以在不修改现有代码的情况下添加新功能。 坏处 可能导致过度设计在简单的系统中过度使用抽象可能导致不必要的复杂性。增加系统的初始设计成本需要在设计初期考虑扩展性可能增加开发时间。 4. 实际案例 违反开放封闭原则的示例 public class ShapeCalculator {public double CalculateArea(object shape){if (shape is Circle){Circle circle (Circle)shape;return Math.PI * circle.Radius * circle.Radius;}else if (shape is Rectangle){Rectangle rectangle (Rectangle)shape;return rectangle.Width * rectangle.Height;}return 0;} }在这个例子中每次添加新形状都需要修改 ShapeCalculator 类。 遵守开放封闭原则的示例 public abstract class Shape {public abstract double CalculateArea(); }public class Circle : Shape {public double Radius { get; set; }public override double CalculateArea(){return Math.PI * Radius * Radius;} }public class Rectangle : Shape {public double Width { get; set; }public double Height { get; set; }public override double CalculateArea(){return Width * Height;} }public class ShapeCalculator {public double CalculateArea(Shape shape){return shape.CalculateArea();} }在这个例子中ShapeCalculator 类不需要修改即可支持新形状。 5. 如何实现开放封闭原则 使用抽象类和接口定义抽象类和接口来隔离变化。依赖于抽象而不是具体实现通过依赖注入等方式使用抽象类和接口。使用设计模式如策略模式、装饰模式等来实现扩展。重构现有代码在不影响现有功能的前提下逐步重构代码以符合开放封闭原则。 3. 里氏替换原则Liskov Substitution Principle 1. 定义 子类必须能够替换父类并且程序的行为不会改变。即子类对象必须能够替换程序中父类对象出现的任何地方保证原有程序的逻辑行为不变。 2. 核心思想 子类继承父类时应该扩展父类的功能而不是改变父类原有的功能子类的行为必须与父类保持一致不能违背父类的契约面向抽象编程依赖父类接口而不是具体实现 3. 为什么要遵守里氏替换原则 好处 保证系统的稳定性子类不会破坏父类的行为约定避免运行时错误提高代码的可复用性可以安全地在任何使用父类的地方使用子类增强系统的可扩展性新增子类不会影响现有系统的行为实现基于契约设计通过接口约定确保行为的一致性 坏处 可能限制继承的使用某些情况下可能需要更灵活的继承关系增加设计难度需要仔细考虑父类的契约和子类的实现可能导致类层次变深为了保持行为一致可能需要增加抽象层次 4. 实际案例 不遵守里氏替换原则的案例 public class Rectangle {public virtual int Width { get; set; }public virtual int Height { get; set; }public int GetArea(){return Width * Height;} }public class Square : Rectangle {public override int Width{set { base.Width base.Height value; }}public override int Height{set { base.Width base.Height value; }} }// 使用示例 Rectangle rect new Square(); rect.Width 5; rect.Height 10; // 违反了矩形的行为约定 Console.WriteLine(rect.GetArea()); // 期望50实际得到100遵守里氏替换原则的案例 public class Rectangle {public int Width { get; set; }public int Height { get; set; }public int GetArea(){return Width * Height;} }public class Square {private Rectangle rectangle new Rectangle();public int Side{get { return rectangle.Width; }set { rectangle.Width rectangle.Height value; }}public int GetArea(){return rectangle.GetArea();} }5. 如何实现里氏替换原则 正确使用继承关系 确保子类扩展而不是改变父类的功能子类必须完全实现父类的方法子类可以有自己的个性 严格遵守契约 子类必须遵守父类的行为约定子类可以适当扩展约定但不能违背 使用组合替代继承 当继承可能破坏父类的行为约定时使用组合将继承关系改为组合关系 面向接口编程 优先使用接口定义行为契约通过接口隔离变化 加强单元测试 编写测试用例验证子类行为确保子类可以在任何使用父类的地方正常工作。 4. 依赖倒置原则Dependency Inversion Principle 依赖倒置原则Dependency Inversion Principle, DIP 是面向对象设计的六大原则之一它的核心思想是高层模块不应该依赖于低层模块二者都应该依赖于抽象抽象不应该依赖于细节细节应该依赖于抽象。简单来说就是通过面向抽象接口或抽象类编程而不是面向实现编程。 1. 定义 * 高层模块不应该依赖低层模块两者都应该依赖其抽象 * 抽象不应该依赖于细节细节应该依赖于抽象高层模块不应该依赖于低层模块二者都应该依赖于抽象。 高层模块通常是指业务逻辑层或核心功能模块。低层模块通常是指具体实现层或基础设施模块。 抽象接口或抽象类不应该依赖于细节具体实现细节应该依赖于抽象。 抽象通常指接口或抽象类。细节通常指具体实现类。 2. 核心思想 依赖倒置原则的核心思想是 通过抽象解耦高层模块和低层模块通过抽象接口或抽象类进行交互而不是直接依赖具体实现。减少代码耦合高层模块不依赖于低层模块的具体实现从而使得系统更灵活、更易扩展。面向接口编程通过定义接口或抽象类屏蔽具体实现细节使代码更加稳定。 3. 为什么要遵守依赖倒置原则 好处 降低系统耦合性通过抽象接口降低了各模块间的依赖提高系统稳定性高层模块不依赖于低层模块的实现细节提高代码可维护性各模块通过抽象接口交互修改实现时不会互相影响提高代码可测试性可以通过抽象接口轻松地模拟依赖对象 坏处 系统抽象层次增加可能会引入更多的接口和抽象类开发成本上升需要进行更详细的前期设计难度增加对开发人员的要求更高需要更好的抽象思维能力 4. 实际案例 不遵守依赖倒置原则的案例 // 高层模块直接依赖低层模块 public class MessageSender {private EmailSender emailSender;public MessageSender(){emailSender new EmailSender(); // 直接依赖具体实现}public void SendMessage(string message){emailSender.SendEmail(message);} }public class EmailSender {public void SendEmail(string message){Console.WriteLine(Sending Email: message);} }遵守依赖倒置原则的案例 // 定义抽象接口 public interface IMessageSender {void Send(string message); }// 低层模块实现接口 public class EmailSender : IMessageSender {public void Send(string message){Console.WriteLine(Sending Email: message);} }public class SmsSender : IMessageSender {public void Send(string message){Console.WriteLine(Sending SMS: message);} }// 高层模块依赖于抽象 public class MessageSender {private readonly IMessageSender _messageSender;public MessageSender(IMessageSender messageSender){_messageSender messageSender;}public void SendMessage(string message){_messageSender.Send(message);} }5. 如何实现依赖倒置原则 定义抽象层 创建接口或抽象类在抽象层定义行为契约确保抽象层稳定性 实现依赖注入 构造函数注入属性注入方法注入使用依赖注入容器 遵循面向接口编程 优先使用接口而不是具体类型避免在高层模块中直接实例化低层模块通过工厂模式创建对象 合理设计抽象 抽象要足够稳定抽象粒度要合适避免过度抽象 使用设计模式 工厂模式抽象工厂模式模板方法模式 5. 接口隔离原则Interface Segregation Principle 接口隔离原则Interface Segregation Principle, ISP 是面向对象设计的六大原则之一其核心思想是客户端不应该被强迫依赖于它不需要的接口。换句话说一个接口应该只包含客户端真正需要的方法不应该将多个不相关的功能强行组合到一个接口中。 1. 定义 接口隔离原则的关键点是 接口应该小而专一 一个接口只应该包含客户端需要的方法避免臃肿和多余。 接口的职责要单一 每个接口应该只负责一种功能避免接口承担过多职责。 2. 核心思想 接口隔离原则的核心思想是通过拆分接口来降低系统的耦合性。当一个接口过于庞大时可能会导致以下问题 实现类需要实现不必要的方法 如果一个实现类只需要接口的一部分功能却被迫实现整个接口就会导致代码膨胀。 接口的修改会影响所有实现类 如果一个庞大的接口被修改所有依赖该接口的实现类都可能需要调整增加维护成本。 违背单一职责原则 一个接口承担了过多的职责导致接口变得难以理解和维护。 通过遵守接口隔离原则可以确保接口的设计更贴合实际需求降低系统的复杂度。 3. 为什么要遵守接口隔离原则 问题如果不遵守会带来以下问题 实现类承担额外的负担 如果一个接口包含了不相关的功能所有实现类都需要实现这些无关的方法即使它们并不需要这些功能。 接口的变更影响范围过大 当一个庞大的接口发生变更时所有依赖该接口的实现类都可能受到影响增加了系统的维护成本。 代码难以复用 一个接口承担过多职责时复用性会降低因为不同的类可能只需要接口的一部分功能。 好处遵守接口隔离原则的优势 提高系统的灵活性 接口更加精简类只需要依赖它真正需要的接口减少了不必要的耦合。 降低维护成本 接口的修改只会影响少量的实现类降低了修改的风险。 提高代码的复用性 小而专一的接口可以更容易被复用。 4. 实际案例 不遵守接口隔离原则的设计 假设我们设计一个动物行为的接口 IAnimal包含以下方法 //错误示例 public interface IAnimal {void Eat();void Fly();void Swim(); } //如果我们有一个 Bird 类和一个 Fish 类需要实现这个接口 public class Bird : IAnimal {public void Eat(){Console.WriteLine(Bird is eating);}public void Fly(){Console.WriteLine(Bird is flying);}public void Swim(){// 鸟不会游泳但必须实现这个方法throw new NotImplementedException(Bird cant swim);} }public class Fish : IAnimal {public void Eat(){Console.WriteLine(Fish is eating);}public void Fly(){// 鱼不会飞但必须实现这个方法throw new NotImplementedException(Fish cant fly);}public void Swim(){Console.WriteLine(Fish is swimming);} } //问题 //Bird 和 Fish 都必须实现它们不需要的方法Swim 或 Fly导致代码臃肿。 //如果接口 IAnimal 增加新的方法如 Run所有实现类都需要修改影响范围过大。//正确示例 public interface IEater {void Eat(); }public interface IFlyer {void Fly(); }public interface ISwimmer {void Swim(); }//然后让 Bird 和 Fish 分别实现它们需要的接口 public class Bird : IEater, IFlyer {public void Eat(){Console.WriteLine(Bird is eating);}public void Fly(){Console.WriteLine(Bird is flying);} }public class Fish : IEater, ISwimmer {public void Eat(){Console.WriteLine(Fish is eating);}public void Swim(){Console.WriteLine(Fish is swimming);} } 5. 如何实现接口隔离原则 拆分接口 将一个大的接口拆分为多个小接口每个接口只包含一种功能。例如将 IAnimal 接口拆分为 IEater、IFlyer 和 ISwimmer 接口。 根据实际需求设计接口 接口的设计应该基于实际需求而不是试图设计一个“万能接口”。 避免接口污染 不要在接口中添加客户端不需要的方法保持接口的精简和专一。 6. 迪米特法则Law of Demeter 迪米特法则Law of Demeter, LoD也称为最少知识原则Least Knowledge Principle, LKP 是面向对象设计中的一项重要原则。它的核心思想是一个对象应当尽可能少地了解其他对象的细节。 换句话说一个模块或类不应该直接依赖于过多的其他模块或类而是通过有限的接口与外部进行通信。 1. 定义 迪米特法则的核心定义是 一个对象只与它直接相关的对象进行通信不应该直接调用其他对象的内部细节。不要“越级”访问对象的成员或方法即避免“对象链式调用”。 非正式的描述** “只与你的直接朋友通信不要和‘陌生人’说话。” 直接朋友当前类的成员变量、方法参数或方法返回值中的对象。陌生人通过其他对象间接获得的对象。 2. 核心思想 迪米特法则的核心思想是降低对象之间的耦合度使系统更加模块化和易于维护。具体包括 减少依赖关系通过限制类之间的通信范围降低系统的耦合性。提高可维护性当一个类发生变化时对其他类的影响会更小。隐藏实现细节通过封装避免暴露不必要的内部细节。 3. 为什么要遵守迪米特法则 问题如果不遵守会带来以下问题** 系统耦合性过高 如果一个对象直接依赖于多个其他对象的具体实现当这些对象发生变化时当前对象也需要修改增加了维护成本。 代码难以复用 高耦合的代码很难在其他场景中复用因为它依赖于太多其他对象。 难以测试 如果一个对象需要依赖多个其他对象才能工作那么单独测试它会变得非常困难。 好处遵守迪米特法则的优势** 降低耦合性 类之间的依赖关系减少使得系统更稳定。 提高模块化 每个类只需要关注自己的职责代码更清晰。 增强可维护性 当一个类发生变化时对其他类的影响更小。 4. 实际案例 不遵守迪米特法则的设计 //错误示例 //假设我们有一个 Person 类和一个 Car 类Person 想通过 Car 的引擎Engine启动汽车 public class Engine {public void Start(){Console.WriteLine(Engine started.);} }public class Car {public Engine GetEngine(){return new Engine();} }public class Person {public void Drive(Car car){// 通过 Car 获取 Engine然后调用 Engine 的方法car.GetEngine().Start();} } //问题 //Person 类直接依赖于 Car 和 Engine 两个类的具体实现。 //如果 Engine 类的实现发生变化例如方法名从 Start 改为 IgnitePerson 类也需要修改。 //Person 类越级访问了 Engine 的内部细节违反了迪米特法则。//正确示例 public class Engine {public void Start(){Console.WriteLine(Engine started.);} }public class Car {private Engine engine new Engine();public void Start(){engine.Start();} }public class Person {public void Drive(Car car){// 直接调用 Car 的方法而不是访问 Car 的内部细节car.Start();} }5. 如何实现迪米特法则 封装内部细节 不要暴露类的内部成员如成员变量或方法通过提供公共方法来对外提供服务。 //错误示例 public Engine GetEngine() { return engine; }//正确示例 public void Start() { engine.Start(); }避免链式调用 链式调用会导致类对多个对象的内部细节产生依赖增加了耦合性。 //错误示例 person.GetCar().GetEngine().Start();//正确示例 person.Drive();只与直接朋友通信 一个类只与它的成员变量、方法参数或方法返回值中的对象通信。 不要通过一个对象访问另一个对象的内部细节。 7. 合成复用原则Composite Reuse Principle 核心思想是尽量使用对象组合Composition来实现代码复用而不是通过继承Inheritance来扩展功能。 1. 定义 合成复用原则的关键定义是 优先使用组合而非继承 通过将现有对象作为新对象的成员变量即组合来复用已有的功能。 避免继承的过度使用 继承虽然是代码复用的一种方式但会导致子类与父类之间的强耦合限制了子类的灵活性。 2. 核心思想 合成复用原则的核心思想是通过组合和委托的方式复用代码降低系统的耦合性提高灵活性和可扩展性。 继承的局限性 继承是一种“白箱复用”父类的实现细节对子类是透明的子类过于依赖父类。继承是一种强耦合关系子类的变化可能受到父类的限制。 组合的优势 组合是一种“黑箱复用”对象的内部实现对外部是不可见的调用方只需通过接口与对象交互。组合降低了耦合性增强了系统的灵活性。 3. 为什么要遵守合成复用原则 问题如果过度使用继承会带来以下问题 父类的修改会影响所有子类 如果父类的实现发生变化所有继承该父类的子类都可能需要调整。 继承限制了子类的灵活性 子类必须遵从父类的结构和行为无法灵活地进行扩展。 代码复用的局限性 继承只能复用单一父类的功能而组合可以复用多个类的功能。 好处遵守合成复用原则的优势 降低耦合性 对象之间通过接口进行交互而不是直接依赖具体实现。 提高灵活性 通过组合可以动态地更换或扩展对象的功能。 增强可维护性 组合的方式更容易进行功能的修改和扩展而不需要改变现有的类。 4. 实际案例 不遵守合成复用原则的设计 //错误示例 //假设我们有一个 Car 类和一个 ElectricCar 类ElectricCar 通过继承 Car 来扩展功能 public class Car {public void Drive(){Console.WriteLine(Driving a car...);} }public class ElectricCar : Car {public void ChargeBattery(){Console.WriteLine(Charging the battery...);} } //问题 //如果 Car 类发生变化例如增加新的方法或修改现有方法ElectricCar 类也需要同步调整。 //如果我们需要一个混合动力车既有燃油车的功能又有电动车的功能会导致复杂的多重继承问题C# 不支持多继承。遵守合成复用原则的设计 //正确示例 //我们可以通过组合的方式将 Car 和 Battery 的功能组合在一起而不是通过继承来扩展功能 public class Car {public void Drive(){Console.WriteLine(Driving a car...);} }public class Battery {public void Charge(){Console.WriteLine(Charging the battery...);} }public class ElectricCar {private Car car new Car();private Battery battery new Battery();public void Drive(){car.Drive();}public void ChargeBattery(){battery.Charge();} } //改进 //ElectricCar 类通过组合 Car 和 Battery 的功能实现代码复用而不是通过继承。 //如果 Car 或 Battery 的实现发生变化只需要修改它们自身不会影响 ElectricCar。 //可以更灵活地扩展功能例如再添加一个 FuelTank 类实现混合动力车的功能。5.如何实现合成复用原则 优先使用组合 将已有类作为新类的成员变量通过组合来复用功能。 示例 public class Engine {public void Start(){Console.WriteLine(Engine started.);} }public class Car {private Engine engine new Engine();public void StartCar(){engine.Start();} }使用接口保证灵活性 通过接口定义行为使类之间的依赖关系更加灵活。 示例 public interface IEngine {void Start(); }public class ElectricEngine : IEngine {public void Start(){Console.WriteLine(Electric engine started.);} }public class Car {private IEngine engine;public Car(IEngine engine){this.engine engine;}public void StartCar(){engine.Start();} }避免继承的滥用 继承应该仅在 “is-a” 关系明确时使用而不是单纯为了代码复用。 错误示例 public class Printer {public void Print(){Console.WriteLine(Printing...);} }public class Scanner : Printer {public void Scan(){Console.WriteLine(Scanning...);} }正确示例 public class Printer {public void Print(){Console.WriteLine(Printing...);} }public class Scanner {public void Scan(){Console.WriteLine(Scanning...);} }public class AllInOnePrinter {private Printer printer new Printer();private Scanner scanner new Scanner();public void Print(){printer.Print();}public void Scan(){scanner.Scan();} }23种设计模式 创建型模式 1. 单例模式Singleton Pattern 1. 定义 单例模式Singleton Pattern是一种创建型设计模式它确保一个类只有一个实例并提供一个全局访问点。 2. 适用场景 当类只能有一个实例且客户端可以从一个众所周知的访问点访问它时当唯一实例应该通过子类化可扩展并且客户端应该能够使用扩展实例而不需要修改代码时需要严格控制全局变量的场景资源共享的场景如数据库连接池、线程池等配置管理类日志记录器 3. 结构 ------------------- | Singleton | ------------------- | - instance | ------------------- | - Singleton() | | GetInstance() | -------------------推荐使用下面的Lazy方法实现线程安全的懒汉模式 using System; using System.IO; using System.Threading;public sealed class SingletonLogger {// 使用LazyT实现线程安全的单例private static readonly LazySingletonLogger _instance new LazySingletonLogger(() new SingletonLogger());// 日志文件路径private readonly string _logFilePath application.log;// 私有构造函数防止外部实例化private SingletonLogger(){// 初始化日志文件File.WriteAllText(_logFilePath, Log started at DateTime.Now \n);}// 全局访问点public static SingletonLogger GetInstance() _instance.Value;// 记录日志方法public void Log(string message){File.AppendAllText(_logFilePath, $[{DateTime.Now}] {message}\n);}// 示例用法public static void Main(string[] args){// 获取单例实例var logger SingletonLogger.GetInstance();// 记录日志logger.Log(Application started);// 尝试创建新实例var anotherLogger SingletonLogger.GetInstance();// 检查是否是同一个实例Console.WriteLine(logger anotherLogger); // 输出True// 记录更多日志logger.Log(Processing data...);logger.Log(Application shutdown);} } 4. 实现步骤 将类的构造函数设为私有防止外部实例化创建一个静态私有变量来保存类的唯一实例提供一个静态公共方法来获取该实例考虑线程安全问题 5. 效果 好处 严格控制实例数量全局访问点方便管理节省系统资源避免对资源的多重占用 坏处 违反单一职责原则既管理实例又处理业务逻辑可能造成代码耦合难以进行单元测试在多线程环境下需要特殊处理 6. 总结 单例模式是一种简单但强大的设计模式它通过控制实例化过程来确保系统中某个类只有一个实例。虽然它有很多优点但也存在一些潜在的问题特别是在多线程环境下需要特别注意线程安全问题。在使用时需要权衡利弊确保在合适的场景下使用。 2. 工厂方法模式Factory Method Pattern 1. 定义 工厂方法模式Factory Method Pattern是一种创建型设计模式它定义了一个创建对象的接口但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 2. 适用场景 当一个类不知道它所需要的对象的类时当一个类希望由它的子类来指定它所创建的对象时当类将创建对象的职责委托给多个帮助子类中的某一个并且你希望将哪一个帮助子类是代理者这一信息局部化时需要灵活、可扩展的框架时需要解耦具体产品与使用者时 3. 结构 ------------------- ------------------- | Creator | | Product | ------------------- ------------------- | FactoryMethod() |------| Operation() | ------------------- -------------------^ ^| | ------------------- ------------------- | ConcreteCreator | | ConcreteProduct | ------------------- ------------------- | FactoryMethod() | | Operation() | ------------------- -------------------4. 实现步骤 创建抽象产品接口创建具体产品类实现接口创建抽象工厂类定义工厂方法创建具体工厂类实现工厂方法客户端通过工厂类创建产品对象 5. 效果 好处 提供灵活的扩展性解耦具体产品与使用者符合开闭原则代码可维护性高便于单元测试 坏处 增加了类的数量增加了系统的复杂性需要额外的设计工作可能引入不必要的抽象层 6. 总结 工厂方法模式通过将对象的创建过程封装在工厂类中实现了创建逻辑与使用逻辑的分离。它提供了一种灵活的方式来创建对象同时保持了代码的可扩展性和可维护性。虽然它增加了系统的复杂性但在需要灵活创建对象的场景中非常有用。 7. 实际案例 - 日志记录器工厂 以下是一个C#工厂方法模式实现示例 using System;// 产品接口 public interface ILogger {void Log(string message); }// 具体产品 - 文件日志 public class FileLogger : ILogger {public void Log(string message){Console.WriteLine($File Logger: {message});} }// 具体产品 - 控制台日志 public class ConsoleLogger : ILogger {public void Log(string message){Console.WriteLine($Console Logger: {message});} }// 抽象工厂 public abstract class LoggerFactory {public abstract ILogger CreateLogger();public void Log(string message){var logger CreateLogger();logger.Log(message);} }// 具体工厂 - 文件日志工厂 public class FileLoggerFactory : LoggerFactory {public override ILogger CreateLogger(){return new FileLogger();} }// 具体工厂 - 控制台日志工厂 public class ConsoleLoggerFactory : LoggerFactory {public override ILogger CreateLogger(){return new ConsoleLogger();} }// 客户端代码 public class Program {public static void Main(string[] args){// 使用文件日志LoggerFactory fileFactory new FileLoggerFactory();fileFactory.Log(This is a file log message);// 使用控制台日志LoggerFactory consoleFactory new ConsoleLoggerFactory();consoleFactory.Log(This is a console log message);} }3. 抽象工厂模式Abstract Factory Pattern 1. 定义 抽象工厂模式Abstract Factory Pattern是一种创建型设计模式它提供一个创建一系列相关或相互依赖对象的接口而无需指定它们具体的类。 2. 适用场景 系统需要独立于其产品的创建、组合和表示时系统需要配置多个产品族中的一个时需要提供一个产品类库且只暴露接口而不是实现时强调一系列相关产品对象的设计约束时需要保证产品一致性时 3. 结构 ------------------- ------------------- | AbstractFactory | | AbstractProductA | ------------------- ------------------- | CreateProductA()|------| Operation() | | CreateProductB()| ------------------- ------------------- ^^ || | ------------------- ------------------- | ConcreteFactory1 | | ProductA1 | ------------------- ------------------- | CreateProductA()| | Operation() | | CreateProductB()| ------------------- ------------------- ^| | ------------------- ------------------- | ConcreteFactory2 | | ProductA2 | ------------------- ------------------- | CreateProductA()| | Operation() | | CreateProductB()| ------------------- -------------------4. 实现步骤 创建抽象产品接口创建具体产品类实现接口创建抽象工厂接口创建具体工厂类实现工厂接口客户端通过抽象工厂接口创建产品对象 5. 效果 好处 隔离具体类的生成易于交换产品系列保证产品一致性符合开闭原则符合单一职责原则 坏处 增加系统复杂性增加类的数量扩展产品族困难增加系统抽象性 6. 总结 抽象工厂模式通过提供一个创建一系列相关或相互依赖对象的接口而不指定它们具体的类实现了产品族的创建与使用的分离。它特别适用于需要保证产品一致性的场景但也会增加系统的复杂性。 7. 实际案例 - 跨平台UI组件 以下是一个C#抽象工厂模式实现示例 // 抽象产品 - 按钮 public interface IButton {void Render();void OnClick(); }// 具体产品 - Windows按钮 public class WindowsButton : IButton {public void Render(){Console.WriteLine(Render a button in Windows style);}public void OnClick(){Console.WriteLine(Handle a Windows button click event);} }// 具体产品 - MacOS按钮 public class MacOSButton : IButton {public void Render(){Console.WriteLine(Render a button in MacOS style);}public void OnClick(){Console.WriteLine(Handle a MacOS button click event);} }// 抽象产品 - 复选框 public interface ICheckbox {void Render();void OnCheck(); }// 具体产品 - Windows复选框 public class WindowsCheckbox : ICheckbox {public void Render(){Console.WriteLine(Render a checkbox in Windows style);}public void OnCheck(){Console.WriteLine(Handle a Windows checkbox check event);} }// 具体产品 - MacOS复选框 public class MacOSCheckbox : ICheckbox {public void Render(){Console.WriteLine(Render a checkbox in MacOS style);}public void OnCheck(){Console.WriteLine(Handle a MacOS checkbox check event);} }// 抽象工厂 public interface IGUIFactory {IButton CreateButton();ICheckbox CreateCheckbox(); }// 具体工厂 - Windows工厂 public class WindowsFactory : IGUIFactory {public IButton CreateButton(){return new WindowsButton();}public ICheckbox CreateCheckbox(){return new WindowsCheckbox();} }// 具体工厂 - MacOS工厂 public class MacOSFactory : IGUIFactory {public IButton CreateButton(){return new MacOSButton();}public ICheckbox CreateCheckbox(){return new MacOSCheckbox();} }// 客户端代码 public class Application {private IButton _button;private ICheckbox _checkbox;public Application(IGUIFactory factory){_button factory.CreateButton();_checkbox factory.CreateCheckbox();}public void RenderUI(){_button.Render();_checkbox.Render();}public void SimulateUserInteraction(){_button.OnClick();_checkbox.OnCheck();} }// 使用示例 public class Program {public static void Main(string[] args){Console.WriteLine(Creating Windows UI:);//具体创建哪一种UI可以由配置文件指定var windowsApp new Application(new WindowsFactory());windowsApp.RenderUI();windowsApp.SimulateUserInteraction();Console.WriteLine(\nCreating MacOS UI:);var macApp new Application(new MacOSFactory());macApp.RenderUI();macApp.SimulateUserInteraction();} }4. 建造者模式Builder Pattern 1. 定义 建造者模式Builder Pattern是一种创建型设计模式它允许你分步骤创建复杂对象。该模式使你能够使用相同的创建过程生成不同类型和表示的对象。 2. 适用场景 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时当构造过程必须允许被构造的对象有不同的表示时当需要更好地控制对象的创建过程时当需要创建的对象包含多个组成部分且这些部分需要按特定顺序组装时当需要避免重叠构造函数问题时 3. 结构 ------------------- ------------------- | Director | | Builder | ------------------- ------------------- | Construct() |------| BuildPartA() | ------------------- | BuildPartB() |^ | GetResult() || -------------------| ^ ------------------- | | Product | | ------------------- ------------------- | PartA | | ConcreteBuilder | | PartB | ------------------- ------------------- | BuildPartA() || BuildPartB() || GetResult() |-------------------4. 实现步骤 创建产品类创建抽象建造者接口创建具体建造者类创建指挥者类客户端通过指挥者创建产品 5. 效果 好处 封装复杂对象的创建过程允许对象分步骤创建复用相同的创建过程符合单一职责原则符合开闭原则 坏处 增加系统复杂性增加类的数量需要额外设计工作可能引入不必要的抽象层 6. 总结 建造者模式通过将复杂对象的构建过程分解为多个简单步骤使得相同的构建过程可以创建不同的表示。它特别适用于需要分步骤创建复杂对象的场景但也会增加系统的复杂性。 7. 实际案例 - 电脑组装 以下是一个C#建造者模式实现示例 // 产品 - 电脑 public class Computer {public string CPU { get; set; }public string RAM { get; set; }public string Storage { get; set; }public string GPU { get; set; }public void DisplayConfiguration(){Console.WriteLine(Computer Configuration:);Console.WriteLine($CPU: {CPU});Console.WriteLine($RAM: {RAM});Console.WriteLine($Storage: {Storage});Console.WriteLine($GPU: {GPU ?? Integrated});} }// 抽象建造者 public interface IComputerBuilder {void SetCPU();void SetRAM();void SetStorage();void SetGPU();Computer GetComputer(); }// 具体建造者 - 游戏电脑 public class GamingComputerBuilder : IComputerBuilder {private Computer _computer new Computer();public void SetCPU(){_computer.CPU Intel Core i9-13900K;}public void SetRAM(){_computer.RAM 32GB DDR5;}public void SetStorage(){_computer.Storage 2TB NVMe SSD;}public void SetGPU(){_computer.GPU NVIDIA RTX 4090;}public Computer GetComputer(){return _computer;} }// 具体建造者 - 办公电脑 public class OfficeComputerBuilder : IComputerBuilder {private Computer _computer new Computer();public void SetCPU(){_computer.CPU Intel Core i5-13400;}public void SetRAM(){_computer.RAM 16GB DDR4;}public void SetStorage(){_computer.Storage 512GB SSD;}public void SetGPU(){// 办公电脑不需要独立显卡}public Computer GetComputer(){return _computer;} }// 指挥者 public class ComputerDirector {public Computer Build(IComputerBuilder builder){builder.SetCPU();builder.SetRAM();builder.SetStorage();builder.SetGPU();return builder.GetComputer();} }// 客户端代码 public class Program {public static void Main(string[] args){var director new ComputerDirector();Console.WriteLine(Building Gaming Computer:);var gamingBuilder new GamingComputerBuilder();var gamingComputer director.Build(gamingBuilder);gamingComputer.DisplayConfiguration();Console.WriteLine(\nBuilding Office Computer:);var officeBuilder new OfficeComputerBuilder();var officeComputer director.Build(officeBuilder);officeComputer.DisplayConfiguration();} }5. 原型模式详解 1. 定义 原型模式Prototype Pattern是一种创建型设计模式它通过复制现有对象来创建新对象而不是通过new关键字实例化。原型模式特别适用于创建成本高的对象或者需要动态配置的对象。 2. 适用场景 需要避免与产品类层次结构耦合时需要动态配置对象时需要减少子类的数量时需要提高对象创建的性能时需要隔离对象的创建和使用时 3. 结构 ------------------- ------------------- | Prototype | | Client | ------------------- ------------------- | Clone() |------| Operation() | ------------------- -------------------^| ------------------- | ConcretePrototype | ------------------- | Clone() | -------------------4. 实现步骤 定义原型接口Prototype实现具体原型类ConcretePrototype实现**Clone()**方法客户端通过**Clone()**方法创建对象 5. 效果 好处 提高对象创建的性能简化对象创建的过程动态配置对象减少子类的数量隔离对象的创建和使用 坏处 需要**实现Clone()**方法可能复杂化对象结构需要处理深拷贝和浅拷贝可能违反封装原则 6. 总结 原型模式通过复制现有对象来创建新对象特别适用于创建成本高的对象。它提高了对象创建的性能但需要注意深拷贝和浅拷贝的问题。 7. 实际案例 - 图形编辑器 以下是一个C#原型模式实现示例 // 原型接口 public interface IGraphic {IGraphic Clone();void Draw(); }// 具体原型1 - 圆形 public class Circle : IGraphic {public int Radius { get; set; }public string Color { get; set; }public Circle(int radius, string color){Radius radius;Color color;}public IGraphic Clone(){return new Circle(Radius, Color);}public void Draw(){Console.WriteLine($Drawing Circle: Radius{Radius}, Color{Color});} }// 具体原型2 - 矩形 public class Rectangle : IGraphic {public int Width { get; set; }public int Height { get; set; }public string Color { get; set; }public Rectangle(int width, int height, string color){Width width;Height height;Color color;}public IGraphic Clone(){return new Rectangle(Width, Height, Color);}public void Draw(){Console.WriteLine($Drawing Rectangle: Width{Width}, Height{Height}, Color{Color});} }// 图形管理器 public class GraphicManager {private Dictionarystring, IGraphic prototypes new Dictionarystring, IGraphic();public void RegisterPrototype(string key, IGraphic prototype){prototypes[key] prototype;}public IGraphic CreateGraphic(string key){if (prototypes.ContainsKey(key)){return prototypes[key].Clone();}throw new ArgumentException($Prototype {key} not found);} }// 客户端代码 public class Program {public static void Main(string[] args){// 创建原型管理器var manager new GraphicManager();// 注册原型manager.RegisterPrototype(RedCircle, new Circle(10, Red));manager.RegisterPrototype(BlueRectangle, new Rectangle(20, 30, Blue));// 使用原型创建对象var circle1 manager.CreateGraphic(RedCircle);var circle2 manager.CreateGraphic(RedCircle);var rectangle manager.CreateGraphic(BlueRectangle);// 绘制图形circle1.Draw();circle2.Draw();rectangle.Draw();// 修改克隆对象if (circle2 is Circle c){c.Radius 15;c.Color Green;c.Draw();}} }代码注解 IGraphic定义图形接口Circle具体原型实现圆形Rectangle具体原型实现矩形Clone()克隆方法实现原型模式Draw()绘制方法展示图形GraphicManager图形管理器管理原型RegisterPrototype()注册原型方法CreateGraphic()创建图形方法 6. 组合模式(Composite Pattern) ★ 1. 定义 组合模式Composite Pattern是一种结构型设计模式它允许你将对象组合成树形结构以表示部分-整体的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 2. 适用场景 需要表示对象的部分-整体层次结构时希望用户忽略组合对象与单个对象的不同统一地使用组合结构中的所有对象时需要处理树形结构的数据时需要对树形结构中的节点进行统一操作时需要动态地添加或删除树形结构中的节点时 3. 结构 ------------------- ------------------- | Component | | Leaf | ------------------- ------------------- | Operation() | | Operation() | | Add(Component) | ------------------- | Remove(Component)| ^ | GetChild(int) | | ------------------- |^ || | ------------------- | | Composite | | ------------------- | | Operation() | | | Add(Component) | | | Remove(Component)| | | GetChild(int) | | ------------------- ||| ------------------- | | Client |--------------- -------------------4. 实现步骤 创建抽象组件接口创建叶子组件类创建组合组件类客户端通过抽象接口操作组件 5. 效果 好处 简化客户端代码更容易添加新类型的组件提供灵活的结构符合开闭原则符合单一职责原则 坏处 设计可能过于通用类型检查可能变得复杂可能违反接口隔离原则增加系统复杂性 6. 总结 组合模式通过将对象组织成树形结构使得客户端可以统一处理单个对象和组合对象。它特别适用于需要表示部分-整体层次结构的场景但可能会增加系统的复杂性。 7. 实际案例 - 文件系统 以下是一个C#组合模式实现示例 // 抽象组件 public abstract class FileSystemComponent {public string Name { get; }protected FileSystemComponent(string name){Name name;}public abstract void Display(int depth);public abstract long GetSize(); }// 叶子组件 - 文件 public class File : FileSystemComponent {private readonly long _size;public File(string name, long size) : base(name){_size size;}public override void Display(int depth){Console.WriteLine(new string(-, depth) Name);}public override long GetSize(){return _size;} }// 组合组件 - 文件夹 public class Directory : FileSystemComponent {private readonly ListFileSystemComponent _children new();public Directory(string name) : base(name) { }public void Add(FileSystemComponent component){_children.Add(component);}public void Remove(FileSystemComponent component){_children.Remove(component);}public override void Display(int depth){Console.WriteLine(new string(-, depth) Name);foreach (var component in _children){component.Display(depth 2);}}public override long GetSize(){return _children.Sum(component component.GetSize());} }// 客户端代码 public class Program {public static void Main(string[] args){// 创建文件var file1 new File(file1.txt, 100);var file2 new File(file2.jpg, 200);var file3 new File(file3.doc, 150);// 创建子目录var subDir new Directory(Sub Directory);subDir.Add(file2);subDir.Add(file3);// 创建根目录var rootDir new Directory(Root Directory);rootDir.Add(file1);rootDir.Add(subDir);// 显示目录结构Console.WriteLine(File System Structure:);rootDir.Display(1);// 计算总大小Console.WriteLine($\nTotal Size: {rootDir.GetSize()} bytes);} }7. 适配器模式Adapter Pattern 1. 定义 适配器模式Adapter Pattern是一种结构型设计模式它允许不兼容的接口之间能够协同工作。适配器模式通过包装对象的方式将一个类的接口转换成客户期望的另一个接口。 2. 适用场景 需要使用现有的类但其接口与需求不匹配时需要创建可复用的类这些类需要与不相关或不可预见的类协同工作时需要使用多个现有的子类但通过子类化每个类来适配它们的接口不现实时需要统一多个不同接口时需要逐步迁移到新系统时 3. 结构 ------------------- ------------------- | Client | | Target | ------------------- ------------------- | Request() |------| Request() | ------------------- -------------------^|| ------------------- ------------------- | Adapter | | Adaptee | ------------------- ------------------- | Request() | | SpecificRequest()| | Adaptee adaptee |-------| | ------------------- -------------------4. 实现步骤 定义目标接口Target创建适配器类Adapter在适配器类中包装被适配者Adaptee客户端通过目标接口调用适配器 5. 效果 好处 解耦客户端与被适配者提高代码复用性增加灵活性符合开闭原则实现接口转换 坏处 增加系统复杂性可能影响性能过度使用可能导致设计混乱增加调试难度 6. 总结 适配器模式通过包装对象的方式实现了接口转换使得不兼容的接口能够协同工作。它特别适用于集成现有代码或统一多个接口的场景但可能会增加系统的复杂性。 7. 实际案例 - 电源适配器 以下是一个C#适配器模式实现示例 // 目标接口 - 标准电源接口 public interface IStandardPowerSupply {void SupplyPower(); }// 被适配者 - 美标电源 public class AmericanPowerPlug {public void SpecificSupply(){Console.WriteLine(Supplying 110V power (American standard));} }// 适配器 - 美标转国标适配器 public class PowerAdapter : IStandardPowerSupply {private readonly AmericanPowerPlug _americanPlug;public PowerAdapter(AmericanPowerPlug americanPlug){_americanPlug americanPlug;}public void SupplyPower(){Console.WriteLine(Converting 110V to 220V...);_americanPlug.SpecificSupply();Console.WriteLine(Power conversion complete, now supplying 220V);} }// 客户端代码 public class Program {public static void Main(string[] args){// 创建美标电源var americanPlug new AmericanPowerPlug();// 创建适配器var adapter new PowerAdapter(americanPlug);// 使用标准接口供电Console.WriteLine(Using power adapter:);adapter.SupplyPower();} }代码注解 IStandardPowerSupply定义标准电源接口AmericanPowerPlug被适配者实现美标电源PowerAdapter适配器类实现标准接口并包装被适配者SupplyPower()适配器方法实现电压转换SpecificSupply()被适配者的特定方法 8. 桥接模式Bridge Pattern 1. 定义 桥接模式Bridge Pattern是一种结构型设计模式它将抽象部分与实现部分分离使它们可以独立变化。通过使用组合而不是继承桥接模式可以避免类的爆炸式增长。 2. 适用场景 需要避免在抽象和实现之间建立永久绑定时抽象和实现都需要通过子类化进行扩展时需要对抽象部分的修改不影响客户端时需要在运行时切换实现时需要共享实现时 3. 结构 ------------------- ------------------- | Abstraction | | Implementor | ------------------- ------------------- | Operation() |------| OperationImpl() | ------------------- -------------------^ ^| | ------------------- ------------------- | RefinedAbstraction| | ConcreteImplementor| ------------------- ------------------- | Operation() | | OperationImpl() | ------------------- -------------------4. 实现步骤 定义抽象接口Abstraction定义实现接口Implementor创建具体实现类ConcreteImplementor创建精化抽象类RefinedAbstraction客户端通过抽象接口调用实现 5. 效果 好处 分离抽象和实现提高可扩展性实现运行时绑定避免类的爆炸符合开闭原则 坏处 增加系统复杂性可能影响性能增加设计难度需要更多类 6. 总结 桥接模式通过组合的方式将抽象与实现分离使得它们可以独立变化。它特别适用于需要避免继承层次过深的场景但可能会增加系统的复杂性。 7. 实际案例 - 图形绘制 以下是一个C#桥接模式实现示例 // 实现接口 - 绘图API public interface IDrawingAPI {void DrawCircle(double x, double y, double radius); }// 具体实现1 - Windows绘图API public class WindowsDrawingAPI : IDrawingAPI {public void DrawCircle(double x, double y, double radius){Console.WriteLine($Windows API: Drawing circle at ({x},{y}) with radius {radius});} }// 具体实现2 - Linux绘图API public class LinuxDrawingAPI : IDrawingAPI {public void DrawCircle(double x, double y, double radius){Console.WriteLine($Linux API: Drawing circle at ({x},{y}) with radius {radius});} }// 抽象类 - 形状 public abstract class Shape {protected IDrawingAPI drawingAPI;protected Shape(IDrawingAPI drawingAPI){this.drawingAPI drawingAPI;}public abstract void Draw();public abstract void ResizeByPercentage(double pct); }// 精化抽象类 - 圆形 public class Circle : Shape {private double x, y, radius;public Circle(double x, double y, double radius, IDrawingAPI drawingAPI): base(drawingAPI){this.x x;this.y y;this.radius radius;}public override void Draw(){drawingAPI.DrawCircle(x, y, radius);}public override void ResizeByPercentage(double pct){radius * pct;} }// 客户端代码 public class Program {public static void Main(string[] args){// 创建不同平台的绘图APIIDrawingAPI windowsAPI new WindowsDrawingAPI();IDrawingAPI linuxAPI new LinuxDrawingAPI();// 创建圆形并使用不同API绘制var circle1 new Circle(1, 2, 3, windowsAPI);var circle2 new Circle(5, 7, 11, linuxAPI);Console.WriteLine(Drawing circles:);circle1.Draw();circle2.Draw();// 调整大小并重新绘制Console.WriteLine(\nResizing and redrawing circles:);circle1.ResizeByPercentage(2.5);circle2.ResizeByPercentage(0.75);circle1.Draw();circle2.Draw();} }代码注解 IDrawingAPI定义绘图接口WindowsDrawingAPIWindows平台的具体实现LinuxDrawingAPILinux平台的具体实现Shape抽象类包含绘图API引用Circle精化抽象类实现具体形状Draw()绘制方法委托给具体实现ResizeByPercentage()调整大小方法 9. 装饰模式Decorator Pattern★ 1. 定义 装饰模式Decorator Pattern是一种结构型设计模式它允许动态地为对象添加功能而不改变其结构。装饰模式通过包装对象的方式提供了比继承更灵活的功能扩展方式。 2. 适用场景 需要动态地添加或撤销对象的功能时需要扩展类的功能但使用继承不切实际时需要组合多个功能时需要避免使用子类进行功能扩展时需要运行时添加功能时 3. 结构 ------------------- ------------------- | Component | | Decorator | ------------------- ------------------- | Operation() |------| Operation() | ------------------- | Component component|^ -------------------| ^| | ------------------- ------------------- | ConcreteComponent | | ConcreteDecorator | ------------------- ------------------- | Operation() | | Operation() | ------------------- | AddedBehavior() |-------------------4. 实现步骤 定义组件接口Component创建具体组件ConcreteComponent创建装饰器基类Decorator创建具体装饰器ConcreteDecorator客户端通过装饰器调用组件 5. 效果 好处 动态添加功能避免继承爆炸符合开闭原则提高灵活性实现功能组合 坏处 增加系统复杂性可能产生大量小对象增加调试难度可能影响性能 6. 总结 装饰模式通过包装对象的方式实现了动态功能扩展。它特别适用于需要运行时添加功能的场景但可能会增加系统的复杂性。 7. 实际案例 - 文本格式化 以下是一个C#装饰模式实现示例 // 组件接口 - 文本组件 public interface ITextComponent {string FormatText(string text); }// 具体组件 - 基础文本 public class PlainText : ITextComponent {public string FormatText(string text){return text;} }// 装饰器基类 public abstract class TextDecorator : ITextComponent {protected ITextComponent textComponent;protected TextDecorator(ITextComponent textComponent){this.textComponent textComponent;}public virtual string FormatText(string text){return textComponent.FormatText(text);} }// 具体装饰器1 - 加粗 public class BoldTextDecorator : TextDecorator {public BoldTextDecorator(ITextComponent textComponent): base(textComponent) { }public override string FormatText(string text){return $b{base.FormatText(text)}/b;} }// 具体装饰器2 - 斜体 public class ItalicTextDecorator : TextDecorator {public ItalicTextDecorator(ITextComponent textComponent): base(textComponent) { }public override string FormatText(string text){return $i{base.FormatText(text)}/i;} }// 具体装饰器3 - 下划线 public class UnderlineTextDecorator : TextDecorator {public UnderlineTextDecorator(ITextComponent textComponent): base(textComponent) { }public override string FormatText(string text){return $u{base.FormatText(text)}/u;} }// 客户端代码 public class Program {public static void Main(string[] args){// 创建基础文本ITextComponent text new PlainText();// 添加装饰text new BoldTextDecorator(text);text new ItalicTextDecorator(text);text new UnderlineTextDecorator(text);// 格式化文本string formattedText text.FormatText(Hello, Decorator Pattern!);Console.WriteLine(formattedText);} }代码注解 ITextComponent定义文本组件接口PlainText具体组件实现基础文本TextDecorator装饰器基类包含组件引用BoldTextDecorator具体装饰器实现加粗功能ItalicTextDecorator具体装饰器实现斜体功能UnderlineTextDecorator具体装饰器实现下划线功能FormatText()格式化方法实现装饰逻辑 10. 外观模式Facade Pattern★ 1. 定义 外观模式为子系统中的一组接口提供一个统一的入口。它定义了一个高层接口使得这一子系统更加容易使用。 2. 适用场景 当需要为复杂的子系统提供一个简单接口时在分层结构的系统中可以使用外观模式定义每层的入口点当客户端与多个子系统之间存在强耦合时可以使用外观模式解耦需要简化复杂系统的访问方式时 3. 结构 ------------------- ------------------- | Facade | | SubSystemA | ------------------- ------------------- | Operation() |------| OperationA() | ------------------- -------------------^ ^| | ------------------- ------------------- | Client | | SubSystemB | ------------------- -------------------| OperationB() |-------------------4. 实现步骤 识别需要简化的复杂子系统创建外观类提供统一的接口在外观类中封装子系统的调用逻辑客户端通过外观类与子系统交互如果需要扩展功能可以创建抽象外观类 5. 效果 好处 简化接口为复杂子系统提供简单易用的接口解耦降低客户端与子系统的耦合度提高灵活性可以独立修改子系统而不影响客户端提高安全性隐藏子系统细节防止客户端误操作 坏处 违反开闭原则新增功能可能需要修改外观类性能开销增加了一层调用可能影响性能过度使用可能导致系统过于依赖外观类 6. 总结 外观模式通过提供一个统一的接口简化了复杂系统的使用。它特别适用于需要简化客户端调用的场景但需要注意不要过度使用以免造成系统过于依赖外观类。 7. 实际案例 - 文件压缩系统 以下是一个C#外观模式实现示例 // 子系统 - 文件读取 public class FileReader {public string Read(string fileName){Console.WriteLine($Reading file: {fileName});return $Content of {fileName};} }// 子系统 - 数据压缩 public class DataCompressor {public string Compress(string data){Console.WriteLine(Compressing data...);return $Compressed({data});} }// 子系统 - 文件写入 public class FileWriter {public void Write(string fileName, string data){Console.WriteLine($Writing data to {fileName});} }// 外观类 public class FileCompressionFacade {private FileReader _reader new FileReader();private DataCompressor _compressor new DataCompressor();private FileWriter _writer new FileWriter();public void CompressFile(string sourceFile, string destFile){// 1. 读取文件string content _reader.Read(sourceFile);// 2. 压缩数据string compressedData _compressor.Compress(content);// 3. 写入文件_writer.Write(destFile, compressedData);Console.WriteLine(File compression completed!);} }// 客户端代码 public class Program {public static void Main(string[] args){FileCompressionFacade facade new FileCompressionFacade();// 使用外观类简化文件压缩过程facade.CompressFile(source.txt, compressed.zip);} }11. 享元模式Flyweight Pattern 1. 定义 享元模式Flyweight Pattern是一种结构型设计模式它通过共享大量细粒度对象来减少内存使用。享元模式通过将对象的内部状态和外部状态分离使得可以在多个对象之间共享相同的内部状态。 2. 适用场景 当应用程序需要创建大量相似对象时当对象的大部分状态可以外部化时当内存使用是一个关键问题时当需要缓存对象以提高性能时当对象的创建成本很高时 3. 结构 ------------------- ------------------- | Flyweight | | FlyweightFactory| ------------------- ------------------- | Operation() |------| GetFlyweight() | ------------------- -------------------^ ^| | ------------------- ------------------- | ConcreteFlyweight | | Client | ------------------- ------------------- | Operation() | | | ------------------- -------------------4. 实现步骤 定义享元接口Flyweight创建具体享元类ConcreteFlyweight创建享元工厂类FlyweightFactory客户端通过享元工厂获取享元对象将外部状态传递给享元对象 5. 效果 好处 减少内存使用通过共享对象减少内存占用提高性能减少对象创建和销毁的开销提高可扩展性可以轻松添加新的享元对象符合单一职责原则将状态分离到不同的类中 坏处 增加复杂性需要管理内部状态和外部状态可能影响性能频繁的外部状态传递可能影响性能增加调试难度共享对象可能导致调试困难 6. 总结 享元模式通过共享大量细粒度对象来减少内存使用。它特别适用于需要创建大量相似对象的场景但可能会增加系统的复杂性。 7. 实际案例 - 文本编辑器 以下是一个C#享元模式实现示例 // 享元接口 - 字符 public interface ICharacter {void Display(int pointSize); }// 具体享元类 - 字符 public class Character : ICharacter {private char _symbol;private int _pointSize;public Character(char symbol){_symbol symbol;}public void Display(int pointSize){_pointSize pointSize;Console.WriteLine($Character: {_symbol}, Point Size: {_pointSize});} }// 享元工厂类 public class CharacterFactory {private Dictionarychar, ICharacter _characters new Dictionarychar, ICharacter();public ICharacter GetCharacter(char key){if (!_characters.ContainsKey(key)){_characters[key] new Character(key);}return _characters[key];} }// 客户端代码 public class Program {public static void Main(string[] args){string document AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ;int pointSize 10;CharacterFactory factory new CharacterFactory();foreach (char c in document){pointSize;ICharacter character factory.GetCharacter(c);character.Display(pointSize);}} }12. 代理模式Proxy Pattern★ 1. 定义 代理模式Proxy Pattern是一种结构型设计模式它为其他对象提供一种代理以控制对这个对象的访问。代理模式通过包装对象的方式可以在访问对象时添加额外的功能。 2. 适用场景 当需要控制对对象的访问时当需要延迟初始化懒加载时当需要访问控制权限检查时当需要记录日志或缓存时当需要远程代理远程方法调用时 3. 结构 ------------------- ------------------- | Subject | | RealSubject | ------------------- ------------------- | Request() |------| Request() | ------------------- -------------------^ ^| | ------------------- | | Proxy | | ------------------- | | Request() | | | RealSubject subject|------------| -------------------4. 实现步骤 定义抽象主题接口Subject创建真实主题类RealSubject创建代理类Proxy客户端通过代理类访问真实主题 5. 效果 好处 控制访问可以在访问对象时添加额外的功能延迟初始化可以延迟对象的创建直到真正需要时提高性能可以通过缓存提高性能符合开闭原则可以轻松添加新的代理类 坏处 增加复杂性需要管理代理类和真实主题类可能影响性能代理类的额外处理可能影响性能增加调试难度代理类可能导致调试困难 6. 总结 代理模式通过包装对象的方式可以在访问对象时添加额外的功能。它特别适用于需要控制对对象的访问的场景但可能会增加系统的复杂性。 7. 实际案例 - 图片加载 以下是一个C#代理模式实现示例 // 抽象主题接口 - 图片 public interface IImage {void Display(); }// 真实主题类 - 图片 public class RealImage : IImage {private string _fileName;public RealImage(string fileName){_fileName fileName;LoadFromDisk();}private void LoadFromDisk(){Console.WriteLine($Loading {_fileName});}public void Display(){Console.WriteLine($Displaying {_fileName});} }// 代理类 - 图片代理 public class ProxyImage : IImage {private RealImage _realImage;private string _fileName;public ProxyImage(string fileName){_fileName fileName;}public void Display(){if (_realImage null){_realImage new RealImage(_fileName);}_realImage.Display();} }// 客户端代码 public class Program {public static void Main(string[] args){IImage image new ProxyImage(test.jpg);// 图片将从磁盘加载image.Display();// 图片不需要从磁盘加载image.Display();} }13. 职责链模式Chain of Responsibility Pattern 1. 定义 职责链模式Chain of Responsibility Pattern是一种行为型设计模式它允许多个对象都有机会处理请求从而避免请求的发送者与接收者之间的耦合。这些对象形成一条链并沿着这条链传递请求直到有对象处理它为止。 2. 适用场景 需要动态指定处理请求的对象时需要避免请求发送者与接收者之间的耦合时需要灵活地分配职责时需要按顺序处理请求时需要动态添加或删除处理者时 3. 结构 ------------------- ------------------- | Handler | | Client | ------------------- ------------------- | SetSuccessor() |------| HandleRequest() | | HandleRequest() | ------------------- -------------------^| ------------------- | ConcreteHandler | ------------------- | HandleRequest() | -------------------4. 实现步骤 定义Handler接口实现ConcreteHandler类实现**SetSuccessor()**方法实现**HandleRequest()**方法客户端通过**HandleRequest()**方法发送请求 5. 效果 好处 降低请求发送者与接收者之间的耦合动态添加或删除处理者灵活地分配职责按顺序处理请求简化对象的职责 坏处 可能降低系统的性能可能增加系统的复杂性可能导致请求的丢失可能增加调试的难度 6. 总结 职责链模式通过链式结构处理请求降低了请求发送者与接收者之间的耦合。它灵活地分配职责但需要注意请求的丢失和系统的性能。 7. 实际案例 - 审批系统 以下是一个C#职责链模式实现示例 // 审批者接口 public interface IApprover {void SetNextApprover(IApprover nextApprover);void ProcessRequest(PurchaseRequest request); }// 具体审批者1 - 经理 public class Manager : IApprover {private IApprover _nextApprover;public void SetNextApprover(IApprover nextApprover){_nextApprover nextApprover;}public void ProcessRequest(PurchaseRequest request){if (request.Amount 1000){Console.WriteLine($Manager approved request #{request.Number});}else if (_nextApprover ! null){_nextApprover.ProcessRequest(request);}} }// 具体审批者2 - 总监 public class Director : IApprover {private IApprover _nextApprover;public void SetNextApprover(IApprover nextApprover){_nextApprover nextApprover;}public void ProcessRequest(PurchaseRequest request){if (request.Amount 5000){Console.WriteLine($Director approved request #{request.Number});}else if (_nextApprover ! null){_nextApprover.ProcessRequest(request);}} }// 具体审批者3 - 总裁 public class President : IApprover {public void SetNextApprover(IApprover nextApprover){// 总裁是最后一个审批者没有下一个审批者}public void ProcessRequest(PurchaseRequest request){if (request.Amount 10000){Console.WriteLine($President approved request #{request.Number});}else{Console.WriteLine($Request #{request.Number} requires an executive meeting!);}} }// 采购请求 public class PurchaseRequest {public int Number { get; set; }public double Amount { get; set; }public string Purpose { get; set; }public PurchaseRequest(int number, double amount, string purpose){Number number;Amount amount;Purpose purpose;} }// 客户端代码 public class Program {public static void Main(string[] args){// 创建审批者var manager new Manager();var director new Director();var president new President();// 设置责任链manager.SetNextApprover(director);director.SetNextApprover(president);// 创建采购请求var requests new ListPurchaseRequest{new PurchaseRequest(1, 800, Office supplies),new PurchaseRequest(2, 3500, Conference equipment),new PurchaseRequest(3, 8500, Server upgrade),new PurchaseRequest(4, 12000, Company retreat)};// 处理请求foreach (var request in requests){manager.ProcessRequest(request);}} }代码注解 IApprover定义审批者接口Manager具体审批者处理金额小于等于1000的请求Director具体审批者处理金额小于等于5000的请求President具体审批者处理金额小于等于10000的请求SetNextApprover()设置下一个审批者ProcessRequest()处理请求PurchaseRequest采购请求类Client客户端代码创建审批者和请求 14. 命令模式Command Pattern 1. 定义 命令模式Command Pattern是一种行为型设计模式它将请求封装为对象从而使你可以用不同的请求对客户进行参数化。命令模式支持撤销操作并可以将命令排队或记录日志。 2. 适用场景 需要将请求调用者与请求执行者解耦时需要支持撤销/重做操作时需要将操作作为一等公民如支持事务时需要支持宏命令组合命令时需要支持命令队列或日志记录时 3. 结构 ------------------- ------------------- | Invoker | | Command | ------------------- ------------------- | SetCommand() |------| Execute() | | ExecuteCommand()| | Undo() | ------------------- -------------------^|| ------------------- | | Receiver | | ------------------- | | Action() |--------------- -------------------4. 实现步骤 定义命令接口Command创建具体命令类ConcreteCommand创建接收者类Receiver创建调用者类Invoker客户端通过调用者执行命令 5. 效果 好处 解耦调用者与执行者支持撤销/重做操作支持组合命令支持命令队列符合开闭原则 坏处 增加系统复杂性可能产生大量命令类增加调试难度可能影响性能 6. 总结 命令模式通过将请求封装为对象实现了调用者与执行者的解耦。它特别适用于需要支持撤销/重做或命令队列的场景但可能会增加系统的复杂性。 7. 实际案例 - 文本编辑器 以下是一个C#命令模式实现示例 // 接收者 - 文档 public class Document {public string Content { get; private set; } string.Empty;public void Write(string text){Content text;}public void Erase(int length){if (length Content.Length)length Content.Length;Content Content.Substring(0, Content.Length - length);}public void Print(){Console.WriteLine($Document Content: {Content});} }// 命令接口 public interface ICommand {void Execute();void Undo(); }// 具体命令 - 写入命令 public class WriteCommand : ICommand {private readonly Document _document;private readonly string _text;public WriteCommand(Document document, string text){_document document;_text text;}public void Execute(){_document.Write(_text);}public void Undo(){_document.Erase(_text.Length);} }// 具体命令 - 删除命令 public class EraseCommand : ICommand {private readonly Document _document;private readonly int _length;private string _erasedText;public EraseCommand(Document document, int length){_document document;_length length;}public void Execute(){_erasedText _document.Content.Substring(_document.Content.Length - _length);_document.Erase(_length);}public void Undo(){_document.Write(_erasedText);} }// 调用者 - 编辑器 public class Editor {private readonly StackICommand _commandHistory new();public void ExecuteCommand(ICommand command){command.Execute();_commandHistory.Push(command);}public void UndoLastCommand(){if (_commandHistory.Count 0){var lastCommand _commandHistory.Pop();lastCommand.Undo();}} }// 客户端代码 public class Program {public static void Main(string[] args){var document new Document();var editor new Editor();// 执行命令editor.ExecuteCommand(new WriteCommand(document, Hello ));editor.ExecuteCommand(new WriteCommand(document, World!));document.Print();// 撤销命令editor.UndoLastCommand();document.Print();// 执行删除命令editor.ExecuteCommand(new EraseCommand(document, 3));document.Print();// 撤销删除editor.UndoLastCommand();document.Print();} }15. 解释器模式Interpreter Pattern 1. 定义 解释器模式Interpreter Pattern是一种行为型设计模式它定义了一个语言的语法表示并使用一个解释器来解释语言中的句子。解释器模式通常用于解析和执行特定领域的语言。 2. 适用场景 当需要解释一种特定领域语言时当语言的语法相对简单时当效率不是关键问题时当需要扩展语言时当需要解析表达式时 3. 结构 ------------------- ------------------- | Context | | AbstractExpression| ------------------- ------------------- | |------| Interpret() | ------------------- -------------------^|| ------------------- | | TerminalExpression| | ------------------- | | Interpret() | | ------------------- || ---------------------- | | NonterminalExpression| | ---------------------- | | Interpret() |-------------| ----------------------4. 实现步骤 定义抽象表达式接口AbstractExpression创建终结符表达式类TerminalExpression创建非终结符表达式类NonterminalExpression创建上下文类Context客户端通过解释器解释表达式 5. 效果 好处 易于扩展语法易于实现简单语法符合单一职责原则符合开闭原则灵活的语法表示 坏处 效率较低难以维护复杂语法增加系统复杂性难以调试 6. 总结 解释器模式通过定义语言的语法表示并使用解释器来解释语言中的句子。它特别适用于解析简单语法的场景但对于复杂语法可能效率较低。 7. 实际案例 - 布尔表达式解释器 以下是一个C#解释器模式实现示例 // 抽象表达式接口 public interface IExpression {bool Interpret(Dictionarystring, bool context); }// 终结符表达式 - 变量 public class VariableExpression : IExpression {private readonly string _name;public VariableExpression(string name){_name name;}public bool Interpret(Dictionarystring, bool context){return context[_name];} }// 非终结符表达式 - 与运算 public class AndExpression : IExpression {private readonly IExpression _expr1;private readonly IExpression _expr2;public AndExpression(IExpression expr1, IExpression expr2){_expr1 expr1;_expr2 expr2;}public bool Interpret(Dictionarystring, bool context){return _expr1.Interpret(context) _expr2.Interpret(context);} }// 非终结符表达式 - 或运算 public class OrExpression : IExpression {private readonly IExpression _expr1;private readonly IExpression _expr2;public OrExpression(IExpression expr1, IExpression expr2){_expr1 expr1;_expr2 expr2;}public bool Interpret(Dictionarystring, bool context){return _expr1.Interpret(context) || _expr2.Interpret(context);} }// 非终结符表达式 - 非运算 public class NotExpression : IExpression {private readonly IExpression _expr;public NotExpression(IExpression expr){_expr expr;}public bool Interpret(Dictionarystring, bool context){return !_expr.Interpret(context);} }// 客户端代码 public class Program {public static void Main(string[] args){// 创建上下文var context new Dictionarystring, bool{{ A, true },{ B, false },{ C, true }};// 创建表达式A AND (B OR C)var expression new AndExpression(new VariableExpression(A),new OrExpression(new VariableExpression(B),new VariableExpression(C)));// 解释表达式bool result expression.Interpret(context);Console.WriteLine($A AND (B OR C) {result});// 创建表达式NOT A OR (B AND C)var expression2 new OrExpression(new NotExpression(new VariableExpression(A)),new AndExpression(new VariableExpression(B),new VariableExpression(C)));// 解释表达式bool result2 expression2.Interpret(context);Console.WriteLine($NOT A OR (B AND C) {result2});} }16. ### 迭代器模式详解 1. 定义 迭代器模式Iterator Pattern是一种行为型设计模式它提供一种方法顺序访问一个聚合对象中的各个元素而又不暴露该对象的内部表示。迭代器模式将遍历和聚合分离使得聚合对象可以独立于遍历算法。 2. 适用场景 需要统一遍历不同的聚合结构时需要隐藏聚合对象的内部结构时需要支持多种遍历方式时需要简化聚合对象的接口时需要并行遍历多个聚合对象时 3. 结构 ------------------- ------------------- | Aggregate | | Iterator | ------------------- ------------------- | CreateIterator()|------| First() | ------------------- | Next() |^ | IsDone() || | CurrentItem() | ------------------- ------------------- | ConcreteAggregate | | ConcreteIterator | ------------------- ------------------- | CreateIterator()| | First() | ------------------- | Next() || IsDone() || CurrentItem() |-------------------4. 实现步骤 定义Iterator接口定义Aggregate接口实现ConcreteIterator类实现ConcreteAggregate类客户端通过Iterator遍历Aggregate 5. 效果 好处 简化聚合对象的接口支持多种遍历方式隐藏聚合对象的内部结构统一遍历不同的聚合结构支持并行遍历 坏处 可能增加系统的复杂性可能降低系统的性能可能增加调试的难度可能导致代码的冗余 6. 总结 迭代器模式通过分离遍历和聚合简化了聚合对象的接口。它支持多种遍历方式但需要注意系统的性能和复杂性。 7. 实际案例 - 图书管理系统 以下是一个C#迭代器模式实现示例 // 迭代器接口 public interface IIteratorT {T First();T Next();bool IsDone();T CurrentItem(); }// 聚合接口 public interface IAggregateT {IIteratorT CreateIterator(); }// 具体聚合 - 图书集合 public class BookCollection : IAggregateBook {private ListBook _books new ListBook();public void Add(Book book){_books.Add(book);}public int Count _books.Count;public Book this[int index]{get _books[index];set _books[index] value;}public IIteratorBook CreateIterator(){return new BookIterator(this);} }// 具体迭代器 - 图书迭代器 public class BookIterator : IIteratorBook {private BookCollection _collection;private int _current 0;public BookIterator(BookCollection collection){_collection collection;}public Book First(){_current 0;return _collection[_current];}public Book Next(){_current;if (!IsDone()){return _collection[_current];}return null;}public bool IsDone(){return _current _collection.Count;}public Book CurrentItem(){return _collection[_current];} }// 图书类 public class Book {public string Title { get; set; }public string Author { get; set; }public int Year { get; set; }public Book(string title, string author, int year){Title title;Author author;Year year;}public override string ToString(){return ${Title} by {Author} ({Year});} }// 客户端代码 public class Program {public static void Main(string[] args){// 创建图书集合var collection new BookCollection();collection.Add(new Book(Design Patterns, Erich Gamma, 1994));collection.Add(new Book(Clean Code, Robert C. Martin, 2008));collection.Add(new Book(Refactoring, Martin Fowler, 1999));// 创建迭代器var iterator collection.CreateIterator();// 遍历图书集合Console.WriteLine(Books in collection:);for (var book iterator.First(); !iterator.IsDone(); book iterator.Next()){Console.WriteLine(book);}} }代码注解 IIterator定义迭代器接口IAggregate定义聚合接口BookCollection具体聚合实现图书集合BookIterator具体迭代器实现图书迭代器Book图书类CreateIterator()创建迭代器方法First()获取第一个元素Next()获取下一个元素IsDone()判断是否遍历完成CurrentItem()获取当前元素 17. 中介者模式 1. 定义 中介者模式Mediator Pattern是一种行为型设计模式它封装了一组对象之间的交互方式使得这些对象不需要显式地相互引用。中介者模式通过集中控制对象之间的通信来降低对象之间的耦合度。 2. 适用场景 系统中对象之间存在复杂的引用关系时需要简化对象之间的交互时需要集中控制对象之间的通信时需要动态改变对象之间的交互方式时需要限制对象之间的直接通信时 3. 结构 ------------------- ------------------- | Mediator | | Colleague | ------------------- ------------------- | Notify() |------| Send() | ------------------- | Receive() |^ -------------------| ^ ------------------- | | ConcreteMediator | | ------------------- | | Notify() | | ------------------- || | ------------------- ------------------- | ConcreteColleague | | ConcreteColleague | ------------------- ------------------- | Send() | | Send() | | Receive() | | Receive() | ------------------- -------------------4. 实现步骤 定义Mediator接口定义Colleague接口实现ConcreteMediator类实现ConcreteColleague类客户端通过Mediator进行对象之间的通信 5. 效果 好处 降低对象之间的耦合度简化对象之间的交互集中控制对象之间的通信支持对象之间的松耦合支持对象之间的动态交互 坏处 可能增加系统的复杂性可能降低系统的性能可能增加调试的难度可能导致中介者的过度复杂 6. 总结 中介者模式通过集中控制对象之间的通信降低了对象之间的耦合度。它简化了对象之间的交互但需要注意中介者的复杂性。 7. 实际案例 - 聊天室系统 以下是一个C#中介者模式实现示例 // 中介者接口 public interface IChatRoomMediator {void SendMessage(string message, User user);void AddUser(User user); }// 具体中介者 - 聊天室 public class ChatRoom : IChatRoomMediator {private ListUser _users new ListUser();public void AddUser(User user){_users.Add(user);}public void SendMessage(string message, User user){foreach (var u in _users){// 不发送消息给自己if (u ! user){u.Receive(message);}}} }// 同事类 - 用户 public abstract class User {protected IChatRoomMediator _mediator;public string Name { get; }public User(string name, IChatRoomMediator mediator){Name name;_mediator mediator;}public abstract void Send(string message);public abstract void Receive(string message); }// 具体同事类 - 聊天用户 public class ChatUser : User {public ChatUser(string name, IChatRoomMediator mediator) : base(name, mediator) { }public override void Send(string message){Console.WriteLine(${Name} sends: {message});_mediator.SendMessage(message, this);}public override void Receive(string message){Console.WriteLine(${Name} receives: {message});} }// 客户端代码 public class Program {public static void Main(string[] args){// 创建中介者var chatRoom new ChatRoom();// 创建用户var john new ChatUser(John, chatRoom);var jane new ChatUser(Jane, chatRoom);var bob new ChatUser(Bob, chatRoom);// 添加用户到聊天室chatRoom.AddUser(john);chatRoom.AddUser(jane);chatRoom.AddUser(bob);// 用户发送消息john.Send(Hi everyone!);jane.Send(Hello John!);bob.Send(Hey guys, whats up?);} }代码注解 IChatRoomMediator定义中介者接口ChatRoom具体中介者实现聊天室User同事类定义用户ChatUser具体同事类实现聊天用户Send()发送消息方法Receive()接收消息方法AddUser()添加用户方法SendMessage()发送消息给所有用户方法 18. 备忘录模式# 1. 定义 备忘录模式Memento Pattern是一种行为型设计模式它允许在不破坏封装性的前提下捕获并保存一个对象的内部状态以便在需要时恢复该状态。 2. 适用场景 需要保存和恢复对象的历史状态时需要实现撤销/重做功能时需要保护对象的封装性时需要隔离状态保存和恢复的细节时需要支持多级撤销操作时 3. 结构 ------------------- ------------------- ------------------- | Originator | | Memento | | Caretaker | ------------------- ------------------- ------------------- | State | | State | | Memento | | CreateMemento() |------| GetState() |------| SaveMemento() | | SetMemento() | ------------------- | RestoreMemento()| ------------------- -------------------4. 实现步骤 定义Originator类定义Memento类定义Caretaker类Originator创建MementoCaretaker保存和恢复Memento 5. 效果 好处 保护对象的封装性简化状态保存和恢复的实现支持撤销/重做功能支持多级撤销操作隔离状态保存和恢复的细节 坏处 可能增加系统的复杂性可能消耗大量内存可能降低系统的性能可能增加调试的难度可能导致状态保存和恢复的不一致 6. 总结 备忘录模式通过保存和恢复对象的内部状态支持撤销/重做功能。它保护了对象的封装性但需要注意内存消耗和性能问题。 7. 实际案例 - 文本编辑器 以下是一个C#备忘录模式实现示例 // 备忘录类 public class TextMemento {public string Text { get; }public TextMemento(string text){Text text;} }// 原发器类 - 文本编辑器 public class TextEditor {private string _text;public void SetText(string text){_text text;}public string GetText(){return _text;}// 创建备忘录public TextMemento CreateMemento(){return new TextMemento(_text);}// 恢复备忘录public void SetMemento(TextMemento memento){_text memento.Text;} }// 管理者类 public class TextEditorHistory {private StackTextMemento _history new StackTextMemento();public void Save(TextEditor editor){_history.Push(editor.CreateMemento());}public void Undo(TextEditor editor){if (_history.Count 0){editor.SetMemento(_history.Pop());}} }// 客户端代码 public class Program {public static void Main(string[] args){var editor new TextEditor();var history new TextEditorHistory();// 编辑文本editor.SetText(First version);history.Save(editor);editor.SetText(Second version);history.Save(editor);editor.SetText(Third version);// 显示当前文本Console.WriteLine(Current text: editor.GetText());// 撤销history.Undo(editor);Console.WriteLine(After undo: editor.GetText());// 再次撤销history.Undo(editor);Console.WriteLine(After second undo: editor.GetText());} }代码注解 TextMemento备忘录类保存文本状态TextEditor原发器类实现文本编辑功能TextEditorHistory管理者类保存和恢复备忘录CreateMemento()创建备忘录方法SetMemento()恢复备忘录方法Save()保存备忘录方法Undo()撤销操作方法SetText()设置文本方法GetText()获取文本方法 19. 观察者模式### 观察者模式详解 1. 定义 观察者模式Observer Pattern是一种行为型设计模式它定义了对象之间的一对多依赖关系使得当一个对象改变状态时所有依赖它的对象都会自动收到通知并更新。 2. 适用场景 需要维护对象之间的一致性时需要实现事件处理系统时需要支持广播通信时需要解耦对象之间的依赖关系时需要实现发布-订阅机制时 3. 结构 ------------------- ------------------- | Subject | | Observer | ------------------- ------------------- | Attach() |------| Update() | | Detach() | ------------------- | Notify() | ^ ------------------- |^ | ------------------- ------------------- | ConcreteSubject | | ConcreteObserver | ------------------- ------------------- | State | | Update() | | GetState() | ------------------- | SetState() | -------------------4. 实现步骤 定义Subject接口定义Observer接口实现ConcreteSubject类实现ConcreteObserver类Subject维护Observer列表Subject状态改变时通知所有Observer 5. 效果 好处 支持对象之间的松耦合支持广播通信支持动态添加和删除观察者支持对象之间的一致性支持发布-订阅机制 坏处 可能增加系统的复杂性可能降低系统的性能可能导致内存泄漏可能增加调试的难度可能导致通知顺序的不确定性 6. 总结 观察者模式通过定义对象之间的一对多依赖关系支持对象之间的松耦合。它支持广播通信但需要注意性能问题和通知顺序。 7. 实际案例 - 股票价格通知系统 以下是一个C#观察者模式实现示例 // 观察者接口 public interface IStockObserver {void Update(string stockSymbol, decimal price); }// 具体观察者 - 投资者 public class Investor : IStockObserver {public string Name { get; }public Investor(string name){Name name;}public void Update(string stockSymbol, decimal price){Console.WriteLine(${Name} received update: {stockSymbol} is now at {price:C});} }// 主题接口 public interface IStockSubject {void Attach(IStockObserver observer);void Detach(IStockObserver observer);void Notify(); }// 具体主题 - 股票 public class Stock : IStockSubject {private string _symbol;private decimal _price;private ListIStockObserver _observers new ListIStockObserver();public Stock(string symbol, decimal price){_symbol symbol;_price price;}public decimal Price{get _price;set{if (_price ! value){_price value;Notify();}}}public void Attach(IStockObserver observer){_observers.Add(observer);}public void Detach(IStockObserver observer){_observers.Remove(observer);}public void Notify(){foreach (var observer in _observers){observer.Update(_symbol, _price);}} }// 客户端代码 public class Program {public static void Main(string[] args){// 创建股票var appleStock new Stock(AAPL, 150.00m);// 创建投资者var john new Investor(John);var jane new Investor(Jane);// 订阅股票appleStock.Attach(john);appleStock.Attach(jane);// 更新股票价格appleStock.Price 155.00m;appleStock.Price 160.00m;// John取消订阅appleStock.Detach(john);// 再次更新股票价格appleStock.Price 165.00m;} }代码注解 IStockObserver观察者接口定义更新方法Investor具体观察者实现投资者IStockSubject主题接口定义附加、分离和通知方法Stock具体主题实现股票Attach()附加观察者方法Detach()分离观察者方法Notify()通知观察者方法Update()更新观察者方法Price股票价格属性 20. 状态模式### 状态模式详解 1. 定义 状态模式State Pattern是一种行为型设计模式它允许一个对象在内部状态改变时改变它的行为使得对象看起来像是修改了它的类。 2. 适用场景 一个对象的行为取决于它的状态并且它必须在运行时根据状态改变它的行为需要消除大量的条件语句时需要封装与特定状态相关的行为时需要实现状态转换时需要支持多态行为时 3. 结构 ------------------- ------------------- | Context | | State | ------------------- ------------------- | State |------| Handle() | | Request() | ------------------- ------------------- ^^ | ------------------- ------------------- | ConcreteContext | | ConcreteStateA | ------------------- ------------------- | Request() | | Handle() | ------------------- -------------------^ ------------------- | | ConcreteStateB | | ------------------- | | Handle() | | -------------------------------4. 实现步骤 定义State接口定义ConcreteState类定义Context类Context维护State引用Context委托State处理请求State处理请求并可能转换状态 5. 效果 好处 封装了与特定状态相关的行为消除了大量的条件语句支持状态转换支持多态行为简化了Context类的实现 坏处 可能增加系统的复杂性可能增加类的数量可能降低系统的性能可能增加调试的难度可能导致状态转换的不确定性 6. 总结 状态模式通过封装与特定状态相关的行为支持状态转换。它消除了大量的条件语句但需要注意类的数量和性能问题。 7. 实际案例 - 订单状态系统 以下是一个C#状态模式实现示例 // 状态接口 public interface IOrderState {void Handle(OrderContext context); }// 具体状态 - 新建订单 public class NewOrderState : IOrderState {public void Handle(OrderContext context){Console.WriteLine(Order is in NEW state. Processing...);context.State new ProcessingOrderState();} }// 具体状态 - 处理中订单 public class ProcessingOrderState : IOrderState {public void Handle(OrderContext context){Console.WriteLine(Order is in PROCESSING state. Shipping...);context.State new ShippedOrderState();} }// 具体状态 - 已发货订单 public class ShippedOrderState : IOrderState {public void Handle(OrderContext context){Console.WriteLine(Order is in SHIPPED state. Delivering...);context.State new DeliveredOrderState();} }// 具体状态 - 已交付订单 public class DeliveredOrderState : IOrderState {public void Handle(OrderContext context){Console.WriteLine(Order is in DELIVERED state. Completed.);context.State null;} }// 上下文类 public class OrderContext {public IOrderState State { get; set; }public OrderContext(){State new NewOrderState();}public void Process(){State?.Handle(this);} }// 客户端代码 public class Program {public static void Main(string[] args){var order new OrderContext();// 处理订单order.Process(); // NEW - PROCESSINGorder.Process(); // PROCESSING - SHIPPEDorder.Process(); // SHIPPED - DELIVEREDorder.Process(); // DELIVERED - Completed} }代码注解 IOrderState状态接口定义处理方法NewOrderState具体状态实现新建订单状态ProcessingOrderState具体状态实现处理中订单状态ShippedOrderState具体状态实现已发货订单状态DeliveredOrderState具体状态实现已交付订单状态OrderContext上下文类维护状态引用State状态属性Process()处理方法Handle()状态处理方法 21. 策略模式 1. 定义 策略模式Strategy Pattern是一种行为型设计模式它定义了一系列算法并将每个算法封装起来使它们可以互相替换。策略模式让算法的变化独立于使用它的客户。 2. 适用场景 一个系统需要动态地在几种算法中选择一种时需要消除大量的条件语句时需要封装与算法相关的行为时需要支持算法的扩展时需要支持算法的复用时 3. 结构 ------------------- ------------------- | Context | | Strategy | ------------------- ------------------- | Strategy |------| Execute() | | Execute() | ------------------- ------------------- ^^ | ------------------- ------------------- | ConcreteContext | | ConcreteStrategyA | ------------------- ------------------- | Execute() | | Execute() | ------------------- -------------------^ ------------------- | | ConcreteStrategyB | | ------------------- | | Execute() | | -------------------------------4. 实现步骤 定义Strategy接口定义ConcreteStrategy类定义Context类Context维护Strategy引用Context委托Strategy执行算法Strategy执行算法 5. 效果 好处 封装了与算法相关的行为消除了大量的条件语句支持算法的扩展支持算法的复用简化了Context类的实现 坏处 可能增加系统的复杂性可能增加类的数量可能降低系统的性能可能增加调试的难度可能导致算法的不确定性 6. 总结 策略模式通过封装与算法相关的行为支持算法的扩展和复用。它消除了大量的条件语句但需要注意类的数量和性能问题。 7. 实际案例 - 支付系统 以下是一个C#策略模式实现示例 // 策略接口 public interface IPaymentStrategy {void Pay(decimal amount); }// 具体策略 - 信用卡支付 public class CreditCardPayment : IPaymentStrategy {public void Pay(decimal amount){Console.WriteLine($Paid {amount} via Credit Card.);} }// 具体策略 - 支付宝支付 public class AlipayPayment : IPaymentStrategy {public void Pay(decimal amount){Console.WriteLine($Paid {amount} via Alipay.);} }// 具体策略 - 微信支付 public class WechatPayment : IPaymentStrategy {public void Pay(decimal amount){Console.WriteLine($Paid {amount} via Wechat.);} }// 上下文类 public class PaymentContext {private IPaymentStrategy _strategy;public PaymentContext(IPaymentStrategy strategy){_strategy strategy;}public void SetStrategy(IPaymentStrategy strategy){_strategy strategy;}public void ExecutePayment(decimal amount){_strategy.Pay(amount);} }// 客户端代码 public class Program {public static void Main(string[] args){var context new PaymentContext(new CreditCardPayment());context.ExecutePayment(100.00m); // 使用信用卡支付context.SetStrategy(new AlipayPayment());context.ExecutePayment(200.00m); // 使用支付宝支付context.SetStrategy(new WechatPayment());context.ExecutePayment(300.00m); // 使用微信支付} }代码注解 IPaymentStrategy策略接口定义支付方法CreditCardPayment具体策略实现信用卡支付AlipayPayment具体策略实现支付宝支付WechatPayment具体策略实现微信支付PaymentContext上下文类维护策略引用_strategy策略属性SetStrategy()设置策略方法ExecutePayment()执行支付方法Pay()支付方法 22. 模版方法模式 1. 定义 模板方法模式Template Method Pattern是一种行为型设计模式它定义了一个算法的骨架并允许子类为算法的某些步骤提供实现。模板方法模式让子类重新定义算法的某些步骤而不改变算法的结构。 2. 适用场景 需要固定算法的结构但允许算法的某些步骤变化时需要消除大量的重复代码时需要封装与算法相关的行为时需要支持算法的扩展时需要支持算法的复用时 3. 结构 ------------------- ------------------- | AbstractClass | | ConcreteClass | ------------------- ------------------- | TemplateMethod()| | PrimitiveOp1() | | PrimitiveOp1() |------| PrimitiveOp2() | | PrimitiveOp2() | ------------------- ------------------- ^^ | ------------------- ------------------- | ConcreteClassA | | ConcreteClassB | ------------------- ------------------- | PrimitiveOp1() | | PrimitiveOp1() | | PrimitiveOp2() | | PrimitiveOp2() | ------------------- -------------------4. 实现步骤 定义AbstractClass定义TemplateMethod定义PrimitiveOp1和PrimitiveOp2定义ConcreteClassConcreteClass实现PrimitiveOp1和PrimitiveOp2AbstractClass调用TemplateMethod 5. 效果 好处 封装了与算法相关的行为消除了大量的重复代码支持算法的扩展支持算法的复用简化了AbstractClass类的实现 坏处 可能增加系统的复杂性可能增加类的数量可能降低系统的性能可能增加调试的难度可能导致算法的不确定性 6. 总结 模板方法模式通过封装与算法相关的行为支持算法的扩展和复用。它消除了大量的重复代码但需要注意类的数量和性能问题。 7. 实际案例 - 数据导出系统 以下是一个C#模板方法模式实现示例 // 抽象类 public abstract class DataExporter {// 模板方法public void Export(){ReadData();ProcessData();WriteData();}// 基本操作 - 读取数据protected abstract void ReadData();// 基本操作 - 处理数据protected abstract void ProcessData();// 基本操作 - 写入数据protected virtual void WriteData(){Console.WriteLine(Writing data to file...);} }// 具体类 - Excel导出 public class ExcelExporter : DataExporter {protected override void ReadData(){Console.WriteLine(Reading data from database for Excel...);}protected override void ProcessData(){Console.WriteLine(Processing data for Excel...);}protected override void WriteData(){base.WriteData();Console.WriteLine(Writing data to Excel file...);} }// 具体类 - CSV导出 public class CsvExporter : DataExporter {protected override void ReadData(){Console.WriteLine(Reading data from database for CSV...);}protected override void ProcessData(){Console.WriteLine(Processing data for CSV...);}protected override void WriteData(){base.WriteData();Console.WriteLine(Writing data to CSV file...);} }// 客户端代码 public class Program {public static void Main(string[] args){DataExporter exporter new ExcelExporter();exporter.Export(); // 导出Excelexporter new CsvExporter();exporter.Export(); // 导出CSV} }代码注解 DataExporter抽象类定义模板方法Export()模板方法ReadData()基本操作读取数据ProcessData()基本操作处理数据WriteData()基本操作写入数据ExcelExporter具体类实现Excel导出CsvExporter具体类实现CSV导出ReadData()具体操作读取数据ProcessData()具体操作处理数据WriteData()具体操作写入数据 23. 访问者模式 1. 定义 访问者模式Visitor Pattern是一种行为型设计模式它定义了一个操作该操作作用于一组对象并允许在不改变这些对象的类的情况下定义新的操作。访问者模式将数据结构与数据操作分离。 2. 适用场景 一个对象结构包含多个类且需要执行不同的操作时需要添加新的操作但不改变对象的类时需要封装与对象结构相关的行为时需要支持操作的扩展时需要支持操作的复用时 3. 结构 ------------------- ------------------- | Visitor | | Element | ------------------- ------------------- | VisitA() |------| Accept() | | VisitB() | ------------------- ------------------- ^^ | ------------------- ------------------- | ConcreteVisitor | | ConcreteElementA | ------------------- ------------------- | VisitA() | | Accept() | | VisitB() | | OperationA() | ------------------- -------------------^ ------------------- | | ConcreteElementB | | ------------------- | | Accept() | | | OperationB() | | -------------------------------4. 实现步骤 定义Visitor接口定义ConcreteVisitor类定义Element接口定义ConcreteElement类Element维护Visitor引用Element委托Visitor执行操作Visitor执行操作 5. 效果 好处 封装了与对象结构相关的行为消除了大量的条件语句支持操作的扩展支持操作的复用简化了Element类的实现 坏处 可能增加系统的复杂性可能增加类的数量可能降低系统的性能可能增加调试的难度可能导致操作的不确定性 6. 总结 访问者模式通过封装与对象结构相关的行为支持操作的扩展和复用。它消除了大量的条件语句但需要注意类的数量和性能问题。 7. 实际案例 - 文档处理系统 以下是一个C#访问者模式实现示例 // 访问者接口 public interface IVisitor {void Visit(TextElement text);void Visit(ImageElement image); }// 具体访问者 - 导出访问者 public class ExportVisitor : IVisitor {public void Visit(TextElement text){Console.WriteLine($Exporting text: {text.Content});}public void Visit(ImageElement image){Console.WriteLine($Exporting image: {image.FileName});} }// 具体访问者 - 打印访问者 public class PrintVisitor : IVisitor {public void Visit(TextElement text){Console.WriteLine($Printing text: {text.Content});}public void Visit(ImageElement image){Console.WriteLine($Printing image: {image.FileName});} }// 元素接口 public interface IElement {void Accept(IVisitor visitor); }// 具体元素 - 文本元素 public class TextElement : IElement {public string Content { get; set; }public TextElement(string content){Content content;}public void Accept(IVisitor visitor){visitor.Visit(this);} }// 具体元素 - 图片元素 public class ImageElement : IElement {public string FileName { get; set; }public ImageElement(string fileName){FileName fileName;}public void Accept(IVisitor visitor){visitor.Visit(this);} }// 对象结构 public class Document {private ListIElement _elements new ListIElement();public void AddElement(IElement element){_elements.Add(element);}public void Accept(IVisitor visitor){foreach (var element in _elements){element.Accept(visitor);}} }// 客户端代码 public class Program {public static void Main(string[] args){var document new Document();document.AddElement(new TextElement(Hello World));document.AddElement(new ImageElement(image.png));var exportVisitor new ExportVisitor();document.Accept(exportVisitor); // 导出文档var printVisitor new PrintVisitor();document.Accept(printVisitor); // 打印文档} }代码注解 IVisitor访问者接口定义访问方法ExportVisitor具体访问者实现导出操作PrintVisitor具体访问者实现打印操作IElement元素接口定义接受方法TextElement具体元素实现文本元素ImageElement具体元素实现图片元素Accept()接受方法Visit()访问方法Document对象结构维护元素列表AddElement()添加元素方法Accept()接受访问者方法
http://www.tj-hxxt.cn/news/230252.html

相关文章:

  • 偷dede网站模板打开网站建设中是什么意思
  • 网站必须做电子标识信息罗湖做网站公司排名
  • 南阳提高网站排名网站建设计划书1200字
  • 昆明市建设局官方网站查学校去哪个网站
  • 网站升级建设方案工业云网站建设
  • 无锡网站制作中心我想要个网站
  • 静态网站 后台seo专员简历
  • 服务器添加网站电子商城网站建设报告
  • 做外贸怎么进入国外的网站电商商城网站建设
  • 重庆网站备案快改网站字体颜色代码
  • 京东网站建设设计框架图重庆seo排名方法
  • 建设银行网站用360浏览器做公司网站需注意什么
  • 宁波专业网站制作设计网站备案怎么查
  • 仿京东电商的网站开发报价做网站到八方资源网怎么样
  • 织梦 网站地图 样式wordpress 添加 常规
  • 网站做优化一般几个字wordpress网页如何上传下载
  • 哪种网站名称容易通过备案审核数据库怎么做两个网站
  • 合肥百度团购网站建设律师用的网站模板
  • 机关门户网站 建设 方案自己想做个网站怎么做的
  • 文创产品设计网站推荐网站切图怎么切
  • 香蜜湖网站建设山西通州集团网站建设
  • 上海做高端网站建设2022年即将上市的手机
  • 网站怎么做移动端的徐州双语网站制作
  • html5网站基础优秀网页
  • 服务类的网站怎么做网站网页区别
  • 任丘住房建设局网站关键词怎么选择技巧
  • 专业制作网站多少钱沈阳企业网站制作公司
  • 电脑怎么创建网站吗成都网站快速排名
  • 重庆新闻发布会直播培训机构优化
  • 创意设计网站推荐北京王府井百货大楼关闭