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

喀什的网站怎么做中小企业网络规划与设计

喀什的网站怎么做,中小企业网络规划与设计,苏州知名网站制作公司,网站开发进程报告参考链接干货分享 | 《设计模式之美》学习笔记 - 知乎 (zhihu.com) 总体来说设计模式分为三大类#xff1a; 创建型模式#xff0c;共5种#xff1a;工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式#xff0c;共7种#xff1a;适配器模式、…参考链接干货分享 | 《设计模式之美》学习笔记 - 知乎 (zhihu.com) 总体来说设计模式分为三大类 创建型模式共5种工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式共7种适配器模式、装饰器模式、代理模式、桥接模式、外观门面模式、组合模式、享元模式。 行为型模式共11种策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、状态模式、命令模式、备忘录模式、访问者模式、中介者模式、解释器模式。 ps标红为常用模式其余不常用。常用的也就44614种模式。 学习设计模式前了解一些设计原则和思想 设计原则和思想 当然这些设计原则和哲学是软件设计中非常重要的概念。它们旨在提高代码的可维护性、可扩展性和可读性。以下是每个原则的详细解释 1. SRP - Single Responsibility Principle (单一职责原则) **定义**一个类应该只有一个引起它变化的原因。 **解释**每个类都应该只有一个职责只有一个导致其变化的原因。如果一个类承担了多个职责当需求变化时就会导致类的多处修改难以维护。 **示例**假设一个类既负责用户数据的保存又负责用户数据的显示这违反了SRP。可以拆分成两个类一个负责数据的保存另一个负责显示。 2. OCP - Open/Closed Principle (开放封闭原则) **定义**软件实体类、模块、函数等应该是对扩展开放的但对修改封闭的。 **解释**应通过扩展系统的行为来实现变化而不是通过修改已有的代码。这减少了修改现有代码带来的风险。 **示例**通过使用抽象类和接口可以在不修改现有类的情况下扩展新功能。 3. LSP - Liskov Substitution Principle (里氏替换原则) **定义**子类型必须能够替换掉它们的基类型。 **解释**任何使用基类型的地方都应该可以透明地使用其子类型。如果子类不能替代父类则可能会破坏程序的正确性。 **示例**假设有一个基类Shape和其子类Rectangle和Square子类的方法不应该违反基类的方法行为。 4. ISP - Interface Segregation Principle (接口隔离原则) **定义**客户端不应该被迫依赖于它们不使用的方法。 **解释**应当为客户端提供专用接口而不是使用一个包含所有方法的庞大接口。这样可以防止客户端依赖不需要的方法。 **示例**将一个庞大的接口拆分成多个小接口每个接口只包含一个客户端需要的方法。 5. DIP - Dependency Inversion Principle (依赖倒置原则) **定义**高层模块不应该依赖低层模块二者都应该依赖于抽象。抽象不应该依赖细节细节应该依赖抽象。 **解释**通过依赖抽象如接口或抽象类而不是具体实现可以减少代码的耦合性使系统更加灵活和可维护。 **示例**使用接口来定义行为具体实现类依赖接口而不是直接依赖具体类。 6. KISS - Keep It Simple, Stupid (保持简单愚蠢) **定义**系统应该尽可能保持简单。 **解释**简单的系统更容易理解、维护和扩展。复杂性应当尽量避免。 **示例**避免过度设计不引入不必要的复杂性。 7. DRY - Dont Repeat Yourself (不要重复自己) **定义**每一块知识在系统中应该有唯一的、明确的、权威的表示。 **解释**避免代码重复重复的代码会导致难以维护和更新。如果一个地方的逻辑改变了需要修改所有相关的地方。 **示例**使用函数、类和模块来封装重复的代码逻辑。 8. LOD - Law of Demeter (迪米特法则) **定义**一个对象应该对其他对象有最少的了解。 **解释**一个对象不应该知道太多其他对象的内部细节。它只应该和直接相关的对象交流减少类之间的耦合。 **示例**在方法中避免调用链如a.getB().getC().doSomething()而是通过中介者或传递方法减少耦合。 9. YAGNI - You Arent Gonna Need It (你不会需要它) **定义**不要实现当前不需要的功能。 **解释**避免过早优化或加入不必要的功能只实现当前需求的功能。这样可以减少代码的复杂性和维护成本。 **示例**在项目初期不要为未来可能的需求实现功能只关注当前的需求。 ### 总结 这些设计原则和哲学是为了帮助开发者编写高质量、易维护和可扩展的代码。理解并应用这些原则可以显著提高软件开发的效率和质量。 创建型设计模式 创建型模式用于解决对象的创建问题封装复杂的创建过程解耦对象的创建代码和使用代码  1 单例模式 单例模式用来创建全局唯一的对象一个类只允许创建一个对象实例。有几种经典的实现方式分别是饿汉式懒汉式、双重检测、静态内部类、枚举。 单例模式是一种设计模式确保一个类只有一个实例并提供对该实例的全局访问点。在Java中实现单例模式的几种经典方式有饿汉式、懒汉式、双重检测、静态内部类和枚举。以下是每种方式的实现示例 1. 饿汉式Eager Initialization 饿汉式在类加载时就创建实例线程安全但可能造成资源浪费。 public class SingletonEager {private static final SingletonEager INSTANCE new SingletonEager();private SingletonEager() {// 私有构造方法防止外部实例化}public static SingletonEager getInstance() {return INSTANCE;} } 2. 懒汉式Lazy Initialization 懒汉式在第一次需要实例时才创建非线程安全。 public class SingletonLazy {private static SingletonLazy instance;private SingletonLazy() {// 私有构造方法防止外部实例化}public static SingletonLazy getInstance() {if (instance null) {instance new SingletonLazy();}return instance;} } 3. 双重检测Double-Checked Locking 双重检测在保证线程安全的同时提高了性能。 public class SingletonDoubleChecked {private static volatile SingletonDoubleChecked instance;private SingletonDoubleChecked() {// 私有构造方法防止外部实例化}public static SingletonDoubleChecked getInstance() {if (instance null) {// 这段代码用于在实例为空时锁定当前类以确保只有一个线程能进入同步块创建实例。 // synchronized关键字确保了同步块内的代码在多线程环境下是安全的。 // 这个锁是为了防止多个线程同时进入创建实例的代码块。synchronized (SingletonDoubleChecked.class) {if (instance null) {instance new SingletonDoubleChecked();}}}return instance;} } 4. 静态内部类Static Inner Class 静态内部类方式利用类加载机制保证线程安全延迟加载且性能高。 public class SingletonStaticInnerClass {private SingletonStaticInnerClass() {// 私有构造方法防止外部实例化}private static class Holder {private static final SingletonStaticInnerClass INSTANCE new SingletonStaticInnerClass();}public static SingletonStaticInnerClass getInstance() {return Holder.INSTANCE;} } 5. 枚举Enum 枚举方式是实现单例模式最简洁和安全的方式天生保证线程安全和防止反序列化创建新对象。 // 定义枚举类型 public enum SingletonEnum {// 唯一实例INSTANCE;// 可以在这里添加其他方法public void doSomething() {System.out.println(Doing something...);}// 示例方法可以保存一些状态private int value;public int getValue() {return value;}public void setValue(int value) {this.value value;} }// 使用枚举单例 public class Main {public static void main(String[] args) {// 访问单例实例SingletonEnum singleton SingletonEnum.INSTANCE;// 调用单例的方法singleton.doSomething();// 设置和获取值singleton.setValue(42);System.out.println(Singleton value: singleton.getValue());} }这几种方式各有优缺点选择适合自己项目需求的方式实现单例模式是关键。 2 工厂模式 工厂模式包括简单工厂、工厂方法、抽象工厂3种细分模式抽象工厂模式不常用。工厂模式用来创建不同但相关类型的对象由给定的参数决定来创建哪种类型的对象。 好的下面是使用Java实现的简单工厂模式和工厂方法模式的示例。 1. 简单工厂模式 简单工厂模式通过一个工厂类根据传入的参数决定创建哪种具体类型的对象。它将对象的创建逻辑集中在一个地方。 #### 示例 假设我们要创建不同类型的产品例如Car和Bike。 // 产品接口 interface Vehicle {void drive(); }// 具体产品类Car class Car implements Vehicle {Overridepublic void drive() {System.out.println(Driving a car.);} }// 具体产品类Bike class Bike implements Vehicle {Overridepublic void drive() {System.out.println(Riding a bike.);} }// 简单工厂类 class VehicleFactory {public static Vehicle createVehicle(String type) {if (type.equalsIgnoreCase(Car)) {return new Car();} else if (type.equalsIgnoreCase(Bike)) {return new Bike();} else {throw new IllegalArgumentException(Unknown vehicle type.);}} }// 使用简单工厂模式 public class SimpleFactoryDemo {public static void main(String[] args) {Vehicle car VehicleFactory.createVehicle(Car);car.drive();Vehicle bike VehicleFactory.createVehicle(Bike);bike.drive();} } 2. 工厂方法模式 工厂方法模式通过定义一个创建对象的接口将实际创建工作推迟到子类中。它让一个类的实例化延迟到其子类。 #### 示例 我们用相同的例子但这次使用工厂方法模式。 // 产品接口 interface Vehicle {void drive(); }// 具体产品类Car class Car implements Vehicle {Overridepublic void drive() {System.out.println(Driving a car.);} }// 具体产品类Bike class Bike implements Vehicle {Overridepublic void drive() {System.out.println(Riding a bike.);} }// 抽象工厂接口 interface VehicleFactory {Vehicle createVehicle(); }// 具体工厂类CarFactory class CarFactory implements VehicleFactory {Overridepublic Vehicle createVehicle() {return new Car();} }// 具体工厂类BikeFactory class BikeFactory implements VehicleFactory {Overridepublic Vehicle createVehicle() {return new Bike();} }// 使用工厂方法模式 public class FactoryMethodDemo {public static void main(String[] args) {VehicleFactory carFactory new CarFactory();Vehicle car carFactory.createVehicle();car.drive();VehicleFactory bikeFactory new BikeFactory();Vehicle bike bikeFactory.createVehicle();bike.drive();} } ### 解释 #### 简单工厂模式 - **工厂类** (VehicleFactory)包含一个静态方法用于根据传入的参数创建不同类型的对象。 - **优点**使用简单集中管理对象创建。 - **缺点**增加新的产品类型时需要修改工厂类代码违反开闭原则。 #### 工厂方法模式 - **抽象工厂接口** (VehicleFactory)定义一个创建对象的方法。 - **具体工厂类** (CarFactory 和 BikeFactory)实现创建对象的方法每个具体工厂负责创建一种具体产品。 - **优点**符合开闭原则可以通过增加新的具体工厂类来扩展系统而不修改现有代码。 - **缺点**增加代码复杂性需要创建更多的类。 这两种模式都有各自的适用场景根据实际需求选择合适的模式是关键。 当然可以简单工厂模式和工厂方法模式各自有其适用的场景和优缺点。了解这些场景可以帮助我们在实际开发中做出更合适的选择。 ### 简单工厂模式适用场景 1. **对象创建逻辑简单且稳定**    - 如果对象创建逻辑比较简单不会经常变化那么简单工厂模式是合适的选择。因为简单工厂模式将所有对象创建逻辑集中在一个地方这样的集中管理非常方便。 2. **客户端只需要知道工厂类**    - 客户端不需要关心具体产品类的实现只需传入参数给工厂类即可获得产品对象。这种场景下简单工厂模式能够降低客户端的复杂度。 3. **产品类型较少**    - 当产品种类较少且变化不频繁时简单工厂模式能够有效管理这些产品的创建。 #### 示例 适用于一个简单的图形绘制工具支持创建不同类型的形状例如圆形、矩形。 public class ShapeFactory {public static Shape createShape(String type) {if (type.equalsIgnoreCase(Circle)) {return new Circle();} else if (type.equalsIgnoreCase(Rectangle)) {return new Rectangle();} else {throw new IllegalArgumentException(Unknown shape type.);}} } ### 工厂方法模式适用场景 1. **对象创建逻辑复杂且多变**    - 当对象的创建过程比较复杂或者对象的创建依赖于具体的配置、参数或外部资源时工厂方法模式可以将这些复杂的创建过程封装在具体工厂类中。 2. **系统需要拓展新的产品类型**    - 如果系统需要在未来拓展新的产品类型而不希望修改已有代码工厂方法模式是理想的选择。它遵循开闭原则通过增加新的具体工厂类来创建新的产品类型。 3. **需要提供一系列相关的产品**    - 当需要创建一系列相关的产品对象且这些产品有一个共同的接口或父类时工厂方法模式可以提供一种灵活且可扩展的方式来创建这些产品。 #### 示例 适用于一个文档处理系统可以创建不同类型的文档例如Word文档、PDF文档。 // 抽象产品接口 interface Document {void open();void save(); }// 具体产品类WordDocument class WordDocument implements Document {Overridepublic void open() {System.out.println(Opening Word document.);}Overridepublic void save() {System.out.println(Saving Word document.);} }// 具体产品类PdfDocument class PdfDocument implements Document {Overridepublic void open() {System.out.println(Opening PDF document.);}Overridepublic void save() {System.out.println(Saving PDF document.);} }// 抽象工厂接口 interface DocumentFactory {Document createDocument(); }// 具体工厂类WordDocumentFactory class WordDocumentFactory implements DocumentFactory {Overridepublic Document createDocument() {return new WordDocument();} }// 具体工厂类PdfDocumentFactory class PdfDocumentFactory implements DocumentFactory {Overridepublic Document createDocument() {return new PdfDocument();} }// 使用工厂方法模式 public class FactoryMethodDemo {public static void main(String[] args) {DocumentFactory wordFactory new WordDocumentFactory();Document wordDoc wordFactory.createDocument();wordDoc.open();wordDoc.save();DocumentFactory pdfFactory new PdfDocumentFactory();Document pdfDoc pdfFactory.createDocument();pdfDoc.open();pdfDoc.save();} } ### 总结 - **简单工厂模式**适用于产品种类少且创建逻辑简单、稳定的场景。它通过一个工厂类集中管理对象创建简化客户端代码但不利于扩展新产品。 - **工厂方法模式**适用于产品种类多且创建逻辑复杂、多变的场景。它通过定义抽象工厂接口和具体工厂类实现了创建逻辑的封装和扩展符合开闭原则利于系统的扩展和维护。 选择哪种模式取决于系统的复杂性和对扩展性的需求。 3.抽象工厂模式 抽象工厂模式是一种创建型设计模式它提供一个接口用于创建一系列相关或相互依赖的对象而无需指定它们的具体类。抽象工厂模式使得客户端可以通过接口创建产品对象从而实现产品族的创建和互换。 ### 适用场景 - **系统要独立于它的产品创建、组合和表示时**。 - **系统要由多个产品系列中的一个来配置时**。 - **当需要强调一组相关的产品对象的设计以便进行联合使用时**。 - **系统提供一个产品类库只有产品接口而不是实现时**。 ### 抽象工厂模式的结构 - **抽象产品Abstract Product**定义了产品的接口。 - **具体产品Concrete Product**实现了抽象产品接口。 - **抽象工厂Abstract Factory**声明了一组创建抽象产品的方法。 - **具体工厂Concrete Factory**实现了创建具体产品对象的方法。 ### 示例GUI 工具包 假设我们有一个跨平台的 GUI 工具包需要创建一系列的按钮和文本框这些按钮和文本框在不同操作系统如 Windows 和 MacOS上有不同的实现。 #### 抽象产品接口 // 抽象产品按钮 interface Button {void paint(); }// 抽象产品文本框 interface TextField {void render(); } #### 具体产品类 // 具体产品Windows 按钮 class WindowsButton implements Button {Overridepublic void paint() {System.out.println(Painting a Windows button.);} }// 具体产品MacOS 按钮 class MacOSButton implements Button {Overridepublic void paint() {System.out.println(Painting a MacOS button.);} }// 具体产品Windows 文本框 class WindowsTextField implements TextField {Overridepublic void render() {System.out.println(Rendering a Windows text field.);} }// 具体产品MacOS 文本框 class MacOSTextField implements TextField {Overridepublic void render() {System.out.println(Rendering a MacOS text field.);} } #### 抽象工厂接口 // 抽象工厂 interface GUIFactory {Button createButton();TextField createTextField(); } #### 具体工厂类 // 具体工厂Windows 工厂 class WindowsFactory implements GUIFactory {Overridepublic Button createButton() {return new WindowsButton();}Overridepublic TextField createTextField() {return new WindowsTextField();} }// 具体工厂MacOS 工厂 class MacOSFactory implements GUIFactory {Overridepublic Button createButton() {return new MacOSButton();}Overridepublic TextField createTextField() {return new MacOSTextField();} } #### 客户端代码 客户端代码通过使用抽象工厂接口来创建产品而无需直接依赖具体产品类。 public class AbstractFactoryDemo {private static Application configureApplication() {Application app;GUIFactory factory;String osName System.getProperty(os.name).toLowerCase();if (osName.contains(win)) {factory new WindowsFactory();} else if (osName.contains(mac)) {factory new MacOSFactory();} else {throw new UnsupportedOperationException(Unsupported OS: osName);}app new Application(factory);return app;}public static void main(String[] args) {Application app configureApplication();app.paint();} }// 客户端类应用程序 class Application {private Button button;private TextField textField;public Application(GUIFactory factory) {button factory.createButton();textField factory.createTextField();}public void paint() {button.paint();textField.render();} } ### 解释 1. **抽象产品接口**Button 和 TextField 定义了产品的公共接口。 2. **具体产品类**WindowsButton, MacOSButton, WindowsTextField, MacOSTextField 实现了抽象产品接口提供具体产品的实现。 3. **抽象工厂接口**GUIFactory 定义了一组创建抽象产品的方法。 4. **具体工厂类**WindowsFactory 和 MacOSFactory 实现了抽象工厂接口负责创建具体产品。 5. **客户端代码**Application 类通过抽象工厂接口创建具体产品并且在 main 方法中配置应用程序的工厂使用工厂创建产品。 ### 总结 抽象工厂模式通过定义创建一系列相关或相互依赖的对象的接口能够有效地分离具体产品的创建逻辑提供灵活的产品族创建方式从而提高系统的可扩展性和可维护性。 总结 简单工厂模式适用于对象创建逻辑简单且稳定产品种类较少的场景。它通过一个工厂类集中管理对象创建但不利于扩展新产品。工厂方法模式适用于对象创建逻辑复杂且多变系统需要扩展新的产品类型时。它通过定义抽象工厂接口和具体工厂类实现创建逻辑的封装和扩展符合开闭原则。抽象工厂模式适用于系统需要独立于产品创建、组合和表示系统要由多个产品系列中的一个来配置或者需要创建一系列相关的产品对象时。它通过定义创建一系列相关或相互依赖对象的接口实现产品族的创建和互换。就像这种GUI库不同类型平台下包含多个组件就适合抽象工厂模式。 3 建造者模式 ### 建造者模式 (Builder Pattern) **定义** 建造者模式是一种创建型设计模式它用于将一个复杂对象的构建过程与它的表示分离使得同样的构建过程可以创建不同的表示。 **优点** 1. **将复杂对象的构建过程封装起来**使客户端代码简化不需要关心构建过程的细节。 2. **支持不同的表示**可以通过不同的建造者来创建不同表示的对象。 3. **逐步构建对象**允许通过分步骤构建复杂对象。 **适用场景** 1. **需要生成的对象具有复杂的内部结构**对象的构建步骤是稳定的但各部分的细节可能经常变化。 2. **需要生成的对象有不同的表示**对象的构建步骤相同但对象的具体表示可能不同。 ### 结构 1. **Product产品类**要创建的复杂对象。 2. **Builder抽象建造者**定义了创建Product的各个子部件的抽象接口。 3. **ConcreteBuilder具体建造者**实现Builder接口构建和装配各个部件。 4. **Director指挥者**负责安排复杂对象的建造顺序。它知道如何构建复杂对象。 ### 示例建造一辆汽车#### 产品类Car public class Car {private String engine;private String wheels;private String body;public void setEngine(String engine) {this.engine engine;}public void setWheels(String wheels) {this.wheels wheels;}public void setBody(String body) {this.body body;}Overridepublic String toString() {return Car [engine engine , wheels wheels , body body ];} } #### 抽象建造者CarBuilder abstract class CarBuilder {protected Car car;public Car getCar() {return car;}public void createNewCar() {car new Car();}public abstract void buildEngine();public abstract void buildWheels();public abstract void buildBody(); } #### 具体建造者SportsCarBuilder 和 SUVCarBuilder class SportsCarBuilder extends CarBuilder {Overridepublic void buildEngine() {car.setEngine(Sports Engine);}Overridepublic void buildWheels() {car.setWheels(Sports Wheels);}Overridepublic void buildBody() {car.setBody(Sports Body);} }class SUVCarBuilder extends CarBuilder {Overridepublic void buildEngine() {car.setEngine(SUV Engine);}Overridepublic void buildWheels() {car.setWheels(SUV Wheels);}Overridepublic void buildBody() {car.setBody(SUV Body);} } #### 指挥者Director class Director {private CarBuilder carBuilder;public void setCarBuilder(CarBuilder carBuilder) {this.carBuilder carBuilder;}public Car getCar() {return carBuilder.getCar();}public void constructCar() {carBuilder.createNewCar();carBuilder.buildEngine();carBuilder.buildWheels();carBuilder.buildBody();} } #### 客户端代码 public class BuilderPatternDemo {public static void main(String[] args) {Director director new Director();// 建造一辆运动型汽车CarBuilder sportsCarBuilder new SportsCarBuilder();director.setCarBuilder(sportsCarBuilder);director.constructCar();Car sportsCar director.getCar();System.out.println(Car built:\n sportsCar);// 建造一辆SUV汽车CarBuilder suvCarBuilder new SUVCarBuilder();director.setCarBuilder(suvCarBuilder);director.constructCar();Car suvCar director.getCar();System.out.println(Car built:\n suvCar);} } ### 解释 1. **产品类Car**包含汽车的组成部分以及设置这些部分的方法。 2. **抽象建造者CarBuilder**定义了构建汽车的步骤。 3. **具体建造者SportsCarBuilder 和 SUVCarBuilder**实现了构建汽车的具体步骤。 4. **指挥者Director**负责组织建造步骤确保按照正确的顺序构建产品。 5. **客户端代码**通过指挥者来构建具体的产品。 ### 总结 建造者模式非常适合用来构建复杂对象尤其是在对象的构建过程涉及多个步骤并且这些步骤可以灵活地配置或组合时。通过使用建造者模式可以将对象的构建过程与其表示分离从而实现代码的可读性、可维护性和扩展性。 4 原型模式 不用过多了解知道即可。 **定义** 原型模式是一种创建型设计模式它允许一个对象再创建另外一个可定制的对象而无需知道如何创建的细节。原型模式通过克隆已有的实例来创建新的对象。 **适用场景** 1. **类初始化消耗较多资源**当类的初始化过程比较复杂或消耗大量资源时通过克隆现有实例可以节省开销。 2. **大量相似对象的创建**在需要创建大量相似对象时通过克隆现有实例可以简化创建过程。 3. **对象的差异化定制**在需要不同配置的对象时可以通过克隆并修改部分属性来实现。 ### 结构 1. **Prototype抽象原型类**定义一个克隆自身的接口。 2. **ConcretePrototype具体原型类**实现克隆自身的方法。 3. **Client客户端类**通过调用原型对象的克隆方法来创建新的对象。 ### 示例图形的克隆#### 抽象原型类Shape public abstract class Shape implements Cloneable {private String id;protected String type;abstract void draw();public String getType() {return type;}public String getId() {return id;}public void setId(String id) {this.id id;}Overridepublic Object clone() {Object clone null;try {clone super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return clone;} } #### 具体原型类Rectangle 和 Circle public class Rectangle extends Shape {public Rectangle() {type Rectangle;}Overridepublic void draw() {System.out.println(Inside Rectangle::draw() method.);} }public class Circle extends Shape {public Circle() {type Circle;}Overridepublic void draw() {System.out.println(Inside Circle::draw() method.);} } #### 原型管理器ShapeCache import java.util.Hashtable;public class ShapeCache {private static HashtableString, Shape shapeMap new HashtableString, Shape();public static Shape getShape(String shapeId) {Shape cachedShape shapeMap.get(shapeId);return (Shape) cachedShape.clone();}public static void loadCache() {Circle circle new Circle();circle.setId(1);shapeMap.put(circle.getId(), circle);Rectangle rectangle new Rectangle();rectangle.setId(2);shapeMap.put(rectangle.getId(), rectangle);} } #### 客户端代码 public class PrototypePatternDemo {public static void main(String[] args) {ShapeCache.loadCache();Shape clonedShape1 ShapeCache.getShape(1);System.out.println(Shape : clonedShape1.getType());clonedShape1.draw();Shape clonedShape2 ShapeCache.getShape(2);System.out.println(Shape : clonedShape2.getType());clonedShape2.draw();} } ### 代码解释 1. **抽象原型类Shape**     - 包含一个 clone() 方法用于克隆对象。     - 包含一些属性和方法这些属性和方法将被具体原型类继承和实现。 2. **具体原型类Rectangle 和 Circle**     - 实现抽象原型类的 draw() 方法定义具体原型的行为。     - 通过构造函数设置对象的类型。 3. **原型管理器ShapeCache**     - loadCache() 方法预加载一些对象实例并存储到一个哈希表中。     - getShape(String shapeId) 方法通过对象的 ID 从哈希表中获取对象并返回其克隆。 4. **客户端代码PrototypePatternDemo**     - 加载缓存对象通过克隆方法获取新对象并使用。 ### 优点 1. **性能提高**通过克隆已有实例来创建对象而不是通过构造函数重新创建减少了开销。 2. **隐藏创建逻辑**客户端不需要知道具体对象的创建细节只需使用原型对象的克隆方法。 ### 缺点 1. **深拷贝和浅拷贝**需要考虑对象的拷贝是浅拷贝还是深拷贝。 2. **复杂性增加**克隆方法的实现可能会比较复杂尤其是当对象有复杂的引用关系时。 ### 总结 原型模式是一种强大的创建型模式它通过克隆现有对象来创建新的对象适用于需要大量相似对象的场景。通过使用原型模式可以提高性能并隐藏对象的创建逻辑使代码更加简洁和易于维护。 结构型设计模式 结构式设计模式主要总结了一些类或对象组合在一起的经典结构这些经典的结构可以解决特定应用场景的问题。 1. 代理模式 代理模式Proxy Pattern是设计模式中的一种结构型模式它提供了对象的代理以控制对这个对象的访问。代理对象可以在对象的实际操作前后添加额外的功能如控制访问、延迟初始化、日志记录等。代理模式主要有三种形式静态代理、动态代理和CGLIB代理。以下是代理模式的基本介绍以及Java版本的实现示例。 代理模式基本概念 意图为其他对象提供一种代理以控制对这个对象的访问。 动机 控制对原对象的访问增强对象的功能懒加载或延迟初始化 代理模式的参与者 抽象主题Subject定义代理和真实对象的共同接口。真实主题RealSubject实现了抽象主题的类。代理Proxy持有一个对真实主题对象的引用并实现抽象主题接口。 Java版本的实现示例 1. 静态代理 步骤 创建接口。创建真实主题类实现接口。创建代理类实现接口并持有真实主题类的引用。 // 1. 定义接口 public interface Subject {void request(); }// 2. 真实主题类 public class RealSubject implements Subject {Overridepublic void request() {System.out.println(RealSubject: Handling request.);} }// 3. 代理类 public class Proxy implements Subject {private RealSubject realSubject;Overridepublic void request() {if (realSubject null) {realSubject new RealSubject();}System.out.println(Proxy: Logging before request.);realSubject.request();System.out.println(Proxy: Logging after request.);} }// 使用代理模式 public class Client {public static void main(String[] args) {Subject proxy new Proxy();proxy.request();} }2. 动态代理 步骤 创建接口。创建真实主题类实现接口。创建动态代理处理类利用Java的Proxy类生成代理对象。 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;// 1. 定义接口 public interface Subject {void request(); }// 2. 真实主题类 public class RealSubject implements Subject {Overridepublic void request() {System.out.println(RealSubject: Handling request.);} }// 3. 动态代理处理类 public class DynamicProxyHandler implements InvocationHandler {private Object realSubject;public DynamicProxyHandler(Object realSubject) {this.realSubject realSubject;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(Proxy: Logging before request.);Object result method.invoke(realSubject, args);System.out.println(Proxy: Logging after request.);return result;} }// 使用动态代理模式 public class Client {public static void main(String[] args) {RealSubject realSubject new RealSubject();Subject proxyInstance (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),new DynamicProxyHandler(realSubject));proxyInstance.request();} }CGLIBCode Generation Library代理是一种在运行时生成子类来实现方法拦截的技术。它是动态代理的一种常用于无法直接使用Java内置动态代理的场景例如代理没有实现接口的类。 ### CGLIB代理的基本概念 CGLIB代理通过生成目标类的子类并覆盖其方法来实现代理。由于它不需要目标类实现任何接口因此可以代理那些没有实现接口的类。但CGLIB代理有一个限制目标类不能是final类因为Java不允许对final类进行子类化。 ### CGLIB代理的应用场景 - **Spring框架**Spring AOP在使用注解或配置进行切面编程时如果目标类没有实现接口Spring默认使用CGLIB代理。 - **无法使用Java内置动态代理的类**例如没有实现接口的类或需要对类的所有方法进行代理。 ### 使用CGLIB代理的示例 要使用CGLIB代理首先需要引入CGLIB库。在Maven中你可以添加以下依赖 dependencygroupIdcglib/groupIdartifactIdcglib/artifactIdversion3.3.0/version /dependency #### 示例代码 import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;// 目标类没有实现任何接口 public class RealSubject {public void request() {System.out.println(RealSubject: Handling request.);} }// CGLIB MethodInterceptor 实现 public class CglibProxy implements MethodInterceptor {private Object target;public CglibProxy(Object target) {this.target target;}// 创建代理对象public Object createProxy() {Enhancer enhancer new Enhancer();enhancer.setSuperclass(target.getClass());enhancer.setCallback(this);return enhancer.create();}Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println(CGLIB Proxy: Logging before request.);Object result proxy.invokeSuper(obj, args);  // 调用父类的方法System.out.println(CGLIB Proxy: Logging after request.);return result;} }// 测试类 public class Client {public static void main(String[] args) {RealSubject realSubject new RealSubject();CglibProxy proxy new CglibProxy(realSubject);RealSubject proxyInstance (RealSubject) proxy.createProxy();proxyInstance.request();} } ### CGLIB代理的原理 1. **动态生成子类**CGLIB通过字节码生成技术在运行时生成目标类的子类。 2. **方法拦截**通过重写子类的方法在方法调用前后添加自定义逻辑如日志记录、权限验证等。 3. **调用父类方法**使用MethodProxy对象调用被代理的父类方法确保原有逻辑的执行。 ### CGLIB代理的优缺点 **优点** - **不依赖接口**可以代理没有实现接口的类。 - **灵活性高**可以对类的所有方法进行代理。 **缺点** - **性能开销**由于需要生成子类性能开销较大。 - **限制**目标类不能是final类目标方法不能是final方法或静态方法。 ### 总结 CGLIB代理提供了一种强大的方法来为没有实现接口的类添加代理逻辑。它广泛应用于AOP、缓存、延迟加载等领域。虽然CGLIB代理性能略低于Java内置动态代理但在某些场景下是不可替代的。理解和使用CGLIB代理可以帮助开发者在实际项目中更加灵活地控制对象的行为。 代理模式的优点 职责分离代理模式将调用过程中的附加职责如日志记录、访问控制从主业务逻辑中分离出来。透明性客户端不需要知道代理对象和真实对象的区别它们可以互换使用。控制访问代理可以控制对真实对象的访问比如在访问前进行权限验证、延迟加载等。 代理模式的缺点 开销代理模式在一定程度上增加了系统的复杂性和调用开销。代码复杂尤其是动态代理理解和维护起来较为复杂。 通过以上示例你可以了解到如何在Java中实现代理模式并理解其基本原理和应用场景。代理模式广泛应用于很多实际开发中例如RPC框架、AOP面向切面编程等。 2. 桥接模式 桥接模式Bridge Pattern是一种结构型设计模式它将抽象部分与实现部分分离使它们可以独立地变化。桥接模式的主要意图是通过组合的方式使两个维度的变化独立开来从而达到解耦的目的。 在桥接模式中会涉及到以下几个角色 1. **抽象Abstraction**定义抽象的接口并持有一个实现接口的引用。 2. **扩展抽象Refined Abstraction**扩展抽象接口通常会在这里调用实现接口的功能。 3. **实现Implementor**定义实现的接口该接口不一定要与抽象接口一致通常提供基本操作。 4. **具体实现Concrete Implementor**实现Implementor接口提供具体的实现。 ### 桥接模式的类图 Abstraction|RefinedAbstraction|Implementor|ConcreteImplementorA|ConcreteImplementorB ### 案例实现 我们以一个简单的图形绘制为例通过桥接模式实现不同颜色的图形绘制。这里抽象部分是图形具体的扩展抽象是不同类型的图形如圆形和方形实现部分是颜色具体实现是不同的颜色如红色和绿色。 #### 抽象部分Abstraction // Abstraction abstract class Shape {protected Color color;protected Shape(Color color) {this.color color;}public abstract void draw(); } #### 扩展抽象Refined Abstraction // RefinedAbstraction class Circle extends Shape {private int radius;protected Circle(Color color, int radius) {super(color);this.radius radius;}Overridepublic void draw() {System.out.print(Drawing Circle with radius radius and );color.applyColor();} }// RefinedAbstraction class Rectangle extends Shape {private int width, height;protected Rectangle(Color color, int width, int height) {super(color);this.width width;this.height height;}Overridepublic void draw() {System.out.print(Drawing Rectangle with width width and height height and );color.applyColor();} } #### 实现部分Implementor // Implementor interface Color {void applyColor(); } #### 具体实现Concrete Implementor // ConcreteImplementorA class RedColor implements Color {Overridepublic void applyColor() {System.out.println(applying Red color.);} }// ConcreteImplementorB class GreenColor implements Color {Overridepublic void applyColor() {System.out.println(applying Green color.);} } #### 客户端代码 public class Client {public static void main(String[] args) {Shape redCircle new Circle(new RedColor(), 10);redCircle.draw();Shape greenRectangle new Rectangle(new GreenColor(), 20, 30);greenRectangle.draw();} } ### 运行结果 Drawing Circle with radius 10 and applying Red color. Drawing Rectangle with width 20 and height 30 and applying Green color. 桥接模式的优点 1. **分离抽象接口及其实现部分**可以分别对它们进行修改而不会对另一部分产生影响。 2. **提高扩展性**通过组合的方式可以自由地扩展抽象部分和实现部分而不会导致类层次结构过于复杂。 3. **符合开闭原则**对扩展开放对修改关闭。增加新的抽象部分和实现部分不需要修改现有代码。 桥接模式的使用场景 1. **需要跨多个平台的图形和窗口系统**例如Java的AWT和Swing。 2. **需要更高的灵活性能够独立地扩展和变化**例如一个系统需要支持不同类型的数据库连接。 3. **系统不希望在抽象和实现部分之间有强耦合**例如文件的不同操作打开、关闭、读取、写入和文件的不同存储本地存储、云存储、网络存储。 3. 装饰器模式 装饰器模式Decorator Pattern是一种结构型设计模式它允许向一个现有的对象添加新的功能同时又不改变其结构。装饰器模式是通过创建一个装饰类来包裹原始类从而在保持类方法签名完整性的前提下提供额外的功能。 装饰器模式通常有以下几个角色 1. **组件Component**这是一个接口或抽象类定义了要被装饰的对象的行为。 2. **具体组件ConcreteComponent**这是一个具体的类实现了组件接口表示被装饰的对象。 3. **装饰Decorator**这是一个抽象类实现了组件接口并持有一个组件对象。它主要是为了给具体装饰角色提供一个公共的接口。 4. **具体装饰ConcreteDecorator**这是一个具体的类继承装饰类并为组件对象添加额外的行为。 ### 类图 Component|-----------------|               | ConcreteComponent   Decorator|-----------------|               |ConcreteDecoratorA   ConcreteDecoratorB ### 代码实现 我们以一个简单的例子来说明装饰器模式。假设我们有一个基本的消息发送功能可以向消息添加加密和压缩功能。 #### 组件Component // Component public interface Message {String getContent(); } #### 具体组件ConcreteComponent // ConcreteComponent public class TextMessage implements Message {private String content;public TextMessage(String content) {this.content content;}Overridepublic String getContent() {return content;} } #### 装饰Decorator // Decorator public abstract class MessageDecorator implements Message {protected Message message;public MessageDecorator(Message message) {this.message message;}Overridepublic String getContent() {return message.getContent();} } #### 具体装饰ConcreteDecorator // ConcreteDecoratorA public class Base64EncodedMessage extends MessageDecorator {public Base64EncodedMessage(Message message) {super(message);}Overridepublic String getContent() {return Base64.getEncoder().encodeToString(message.getContent().getBytes());} }// ConcreteDecoratorB public class CompressedMessage extends MessageDecorator {public CompressedMessage(Message message) {super(message);}Overridepublic String getContent() {return compress(message.getContent());}private String compress(String content) {// A simple mock compression, real compression logic can be more complexreturn content.substring(0, content.length() / 2);} } #### 客户端代码 public class Client {public static void main(String[] args) {Message message new TextMessage(Hello, World!);// Add base64 encodingMessage base64Message new Base64EncodedMessage(message);System.out.println(base64Message.getContent());// Add compressionMessage compressedMessage new CompressedMessage(message);System.out.println(compressedMessage.getContent());// Add both encoding and compressionMessage encodedAndCompressedMessage new CompressedMessage(base64Message);System.out.println(encodedAndCompressedMessage.getContent());} } ### 运行结果 SGVsbG8sIFdvcmxkIQ Hello U0dWc2JHVT0 ### 装饰器模式的优点 1. **更灵活**相比于继承装饰器模式提供了一种更灵活的方式来动态地扩展对象的功能。 2. **遵循开闭原则**可以在不修改现有代码的情况下向对象添加新的功能。比如这个例子里不改变原有的消息类但可以加密压缩等。 3. **职责分离**每个装饰器都有其特定的功能不同的装饰器可以相互组合来实现复杂的功能。 ### 装饰器模式的缺点 1. **复杂性增加**如果使用过多的装饰器系统会变得复杂难以理解和维护。 2. **调试困难**由于装饰器的多层嵌套调试时需要逐层跟踪可能会比较困难。 ### 装饰器模式的使用场景 1. **需要动态地为对象添加功能**例如Java I/O 类库中的各种流处理类如 BufferedReader、InputStreamReader 等。 2. **需要在不影响其他对象的情况下为特定对象添加功能**。 3. **需要对一个对象的功能进行多个组合**。 4. 适配器模式 适配器模式Adapter Pattern是一种结构型设计模式它允许将一个类的接口转换成客户希望的另一个接口使得原本由于接口不兼容而不能一起工作的类可以一起工作。适配器模式可以分为对象适配器和类适配器两种形式。 ### 类图 Target|----------------|              |Adapter         Adaptee|ConcreteAdapter ### 适配器模式的角色 1. **目标接口Target**定义客户端使用的接口。 2. **适配者类Adaptee**定义一个已经存在的接口这个接口需要适配。 3. **适配器Adapter**实现目标接口并通过在内部包装一个适配者对象将目标接口与适配者接口连接起来。 类适配器模式 类适配器模式使用多继承来实现适配器继承了目标接口和适配者类。由于Java不支持多继承类适配器模式在Java中并不常见但我们仍然可以通过其他方式来实现。 // Target interface public interface Target {void request(); }// Adaptee class public class Adaptee {public void specificRequest() {System.out.println(Adaptees specific request.);} }// Adapter class public class Adapter extends Adaptee implements Target {Overridepublic void request() {specificRequest();} }// Client code public class Client {public static void main(String[] args) {Target target new Adapter();target.request();} } 对象适配器模式 对象适配器模式通过组合即在适配器内部持有一个适配者对象来实现。相比于类适配器模式对象适配器模式在Java中更为常见。 // Target interface public interface Target {void request(); }// Adaptee class public class Adaptee {public void specificRequest() {System.out.println(Adaptees specific request.);} }// Adapter class,直接实现目标接口不用继承 待适配的类 public class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee adaptee;}Overridepublic void request() {adaptee.specificRequest();} }// Client code public class Client {public static void main(String[] args) {Adaptee adaptee new Adaptee();Target target new Adapter(adaptee);target.request();} } ### 适配器模式的优点 1. **单一职责原则**可以将接口或数据转换代码从业务逻辑中分离出来。 2. **开闭原则**新的适配器可以随时被添加到程序中使得新的适配者类可以无缝地融入系统。 ### 适配器模式的缺点 1. **复杂性增加**系统中引入了额外的适配器层增加了代码的复杂性。 2. **性能开销**由于增加了一层间接调用可能会导致性能的轻微下降。 ### 适配器模式的使用场景 1. **希望复用一些现有的类但接口又与复用环境要求不一致**。 2. **需要统一多个类的接口时**可以通过适配器模式将它们的接口统一起来供外部使用。 3. **需要使用一些现有的子系统但这些子系统的接口并不符合需求**。 通过适配器模式我们可以在不修改现有代码的情况下使得原本由于接口不兼容而不能一起工作的类可以一起工作。这种模式非常适用于系统集成和第三方库的使用场景。 类适配器 vs 对象适配器 实现方式 类适配器通过继承来实现它继承了适配者类并实现了目标接口。对象适配器通过组合来实现它在内部包含一个适配者类的实例。 灵活性 类适配器不够灵活因为它是通过继承来实现的所以无法适配适配者类的子类。对象适配器更灵活因为它是通过组合来实现的可以适配适配者类及其子类。 复用性 类适配器复用性较低因为它是通过继承实现的需要为每个适配者类创建一个适配器。对象适配器复用性较高因为它是通过组合实现的可以复用一个适配器类来适配多个适配者类。 5. 门面模式Facade Pattern 门面模式Facade Pattern是一种结构型设计模式提供了一个简化的接口来访问复杂系统中的子系统。它通过定义一个高层接口让子系统更容易使用简化了客户端的交互。 门面模式的主要目的是降低系统的复杂性提供一个统一的接口来访问子系统的一群接口从而使得系统更加易用和便于维护。 门面模式的优点 1. **简化使用**隐藏子系统的复杂性使得客户端可以更简单地使用子系统。 2. **松耦合**客户端与子系统的实现解耦客户端只需要知道门面的接口而不需要了解子系统的具体实现。 3. **更好的分层**可以在系统的不同层次之间创建一个清晰的分界线。 示例代码 假设我们有一个复杂的家庭影院系统包括电视、音响、DVD播放器、灯光等子系统。我们可以通过门面模式来简化家庭影院系统的操作。 1. 子系统类 // 子系统类之一电视 public class TV {public void on() {System.out.println(TV is ON);}public void off() {System.out.println(TV is OFF);} }// 子系统类之二音响 public class SoundSystem {public void on() {System.out.println(SoundSystem is ON);}public void off() {System.out.println(SoundSystem is OFF);}public void setVolume(int volume) {System.out.println(SoundSystem volume set to volume);} }// 子系统类之三DVD播放器 public class DVDPlayer {public void on() {System.out.println(DVDPlayer is ON);}public void off() {System.out.println(DVDPlayer is OFF);}public void play(String movie) {System.out.println(Playing movie: movie);} }// 子系统类之四灯光 public class Lights {public void dim() {System.out.println(Lights are dimmed);}public void on() {System.out.println(Lights are ON);} } 2. 门面类 // 门面类家庭影院门面 public class HomeTheaterFacade {private TV tv;private SoundSystem soundSystem;private DVDPlayer dvdPlayer;private Lights lights;public HomeTheaterFacade(TV tv, SoundSystem soundSystem, DVDPlayer dvdPlayer, Lights lights) {this.tv tv;this.soundSystem soundSystem;this.dvdPlayer dvdPlayer;this.lights lights;}public void watchMovie(String movie) {System.out.println(Get ready to watch a movie...);lights.dim();tv.on();soundSystem.on();soundSystem.setVolume(20);dvdPlayer.on();dvdPlayer.play(movie);}public void endMovie() {System.out.println(Shutting movie theater down...);lights.on();tv.off();soundSystem.off();dvdPlayer.off();} } 3. 客户端代码 // 客户端代码 public class Client {public static void main(String[] args) {TV tv new TV();SoundSystem soundSystem new SoundSystem();DVDPlayer dvdPlayer new DVDPlayer();Lights lights new Lights();HomeTheaterFacade homeTheater new HomeTheaterFacade(tv, soundSystem, dvdPlayer, lights);homeTheater.watchMovie(Inception);homeTheater.endMovie();} } ### 解释 1. **子系统类**包括 TV、SoundSystem、DVDPlayer 和 Lights它们分别表示家庭影院系统的不同部分每个类都有自己的方法来控制设备的操作。 2. **门面类**HomeTheaterFacade 封装了子系统的复杂性提供了简化的接口watchMovie 和 endMovie来控制整个家庭影院系统。 3. **客户端代码**Client 只需要与 HomeTheaterFacade 交互而不需要了解家庭影院系统的内部实现细节。 门面模式通过提供一个统一的接口使得客户端代码可以更加简单和直观地使用复杂的子系统从而提高了系统的可维护性和易用性。 6. 组合模式Composite Pattern 组合模式Composite Pattern是一种结构型设计模式它将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 组合模式的优点 1. **清晰的层次结构**定义了包含基本对象和组合对象的树形结构。 2. **一致性**用户可以一致地对待单个对象和组合对象。 3. **易于扩展**新增叶子节点和组合节点都很容易无需修改现有类。 ### 示例代码 假设我们有一个文件系统其中包含文件和文件夹。文件夹可以包含文件和其他文件夹。我们可以使用组合模式来表示这种结构。 1. 组件接口 import java.util.ArrayList; import java.util.List;// 抽象组件 abstract class FileSystemComponent {protected String name;public FileSystemComponent(String name) {this.name name;}public abstract void show();public void add(FileSystemComponent component) {throw new UnsupportedOperationException();}public void remove(FileSystemComponent component) {throw new UnsupportedOperationException();}public FileSystemComponent getChild(int i) {throw new UnsupportedOperationException();} } 2. 叶子节点类 // 叶子节点文件 class File extends FileSystemComponent {public File(String name) {super(name);}Overridepublic void show() {System.out.println(File: name);} } 3. 组合节点类 // 组合节点文件夹 class Folder extends FileSystemComponent {private ListFileSystemComponent components new ArrayList();public Folder(String name) {super(name);}Overridepublic void show() {System.out.println(Folder: name);for (FileSystemComponent component : components) {component.show();}}Overridepublic void add(FileSystemComponent component) {components.add(component);}Overridepublic void remove(FileSystemComponent component) {components.remove(component);}Overridepublic FileSystemComponent getChild(int i) {return components.get(i);} } 4. 客户端代码 // 客户端代码 public class Client {public static void main(String[] args) {FileSystemComponent file1 new File(File1.txt);FileSystemComponent file2 new File(File2.txt);FileSystemComponent file3 new File(File3.txt);FileSystemComponent folder1 new Folder(Folder1);FileSystemComponent folder2 new Folder(Folder2);folder1.add(file1);folder1.add(file2);folder2.add(folder1);folder2.add(file3);folder2.show();} } ### 解释 1. **组件接口**FileSystemComponent 是一个抽象类定义了文件系统组件的基本行为包括 show、add、remove 和 getChild 方法。默认情况下add、remove 和 getChild 方法会抛出 UnsupportedOperationException因为叶子节点不支持这些操作。 2. **叶子节点类**File 类是 FileSystemComponent 的子类表示文件。在 show 方法中它仅输出文件的名称。 3. **组合节点类**Folder 类也是 FileSystemComponent 的子类表示文件夹。它包含一个 ListFileSystemComponent 来存储其子组件。在 show 方法中它输出文件夹的名称并递归地调用每个子组件的 show 方法。它还实现了 add、remove 和 getChild 方法来管理其子组件。 4. **客户端代码**在 Client 类中我们创建了一些文件和文件夹并将文件添加到文件夹中。通过调用 folder2.show() 方法输出整个文件系统的层次结构。 这意味着客户端代码不需要区分 File 和 Folder可以统一对待它们。这种一致性使得代码更加简洁和灵活。通过抽象类 FileSystemComponent客户端只需要调用组件的接口方法而不需要关心组件的具体实现类型。  ### 总结 组合模式通过将对象组合成树形结构来表示“部分-整体”的层次结构允许客户端以一致的方式处理单个对象和组合对象。它适用于需要处理树形结构的场景如文件系统、UI组件树等。 7. 享元模式 享元模式Flyweight Pattern是一种结构型设计模式主要用于减少程序中对象的数量从而节省内存和提高性能。它通过共享细粒度对象将那些相似或相同的对象共享起来从而避免对象的重复创建。 ### 核心思想 享元模式的核心思想是通过共享来减少内存的使用将对象中的可变部分和不可变部分分开只将不可变部分进行共享从而减少内存消耗。这个模式特别适合用于有大量重复对象的场景。 ### 适用场景 1. **大量相似对象**当程序中有大量相似或相同的对象时享元模式可以减少内存开销。 2. **对象的创建代价高**对象的创建代价较高而对象之间的差异非常小可以通过共享对象减少创建次数。 ### 组成部分 享元模式主要包括以下几个部分 1. **Flyweight享元接口**定义了对象的接口通过这个接口可以接受外部状态并进行操作。 2. **ConcreteFlyweight具体享元类**实现了享元接口存储对象的内部状态。 3. **UnsharedConcreteFlyweight非共享具体享元类**并非所有的享元对象都可以共享非共享对象可以通过这个类来实现。 4. **FlyweightFactory享元工厂**负责创建和管理享元对象确保可以共享的对象被适当地复用。 5. **Client客户端**使用享元对象的客户端。 ### Java 实现 以下是一个使用享元模式的Java代码示例模拟一个简单的文字处理器其中的字符对象会被共享。 import java.util.HashMap; import java.util.Map;// Flyweight 接口 interface CharacterFlyweight {void display(int fontSize); }// ConcreteFlyweight 实现享元接口 class ConcreteCharacter implements CharacterFlyweight {private final char character;public ConcreteCharacter(char character) {this.character character;}Overridepublic void display(int fontSize) {System.out.println(Character: character , Font size: fontSize);} }// FlyweightFactory 享元工厂 class CharacterFactory {private final MapCharacter, CharacterFlyweight characterMap new HashMap();public CharacterFlyweight getCharacter(char character) {CharacterFlyweight flyweight characterMap.get(character);if (flyweight null) {flyweight new ConcreteCharacter(character);characterMap.put(character, flyweight);}return flyweight;} }// Client 客户端 public class FlyweightPatternDemo {public static void main(String[] args) {CharacterFactory factory new CharacterFactory();String document hello world;int[] fontSizes {12, 14, 16, 18, 20};for (int i 0; i document.length(); i) {CharacterFlyweight character factory.getCharacter(document.charAt(i));character.display(fontSizes[i % fontSizes.length]);}} } ### 代码解释 - **CharacterFlyweight**享元接口定义了一个display方法用于展示字符和字体大小。 - **ConcreteCharacter**具体享元类实现了CharacterFlyweight接口内部保存了字符这个不可变状态。 - **CharacterFactory**享元工厂类负责创建和管理享元对象。通过这个工厂客户端可以获取共享的字符对象。 - **FlyweightPatternDemo**客户端通过工厂获取字符对象并展示它们减少了字符对象的重复创建。 ### 优点 1. **减少内存消耗**通过共享对象避免了大量相似对象的重复创建从而减少内存的使用。 2. **提高性能**减少了创建对象的开销特别是在需要大量对象的场景中性能提升显著。 ### 缺点 1. **增加复杂性**引入共享对象的管理和区分外部状态与内部状态的逻辑增加了系统的复杂性。 2. **非共享部分的处理**如果对象之间的差异较大享元模式可能会变得复杂且不易维护。 ### 总结 享元模式是一种通过共享来减少内存使用的模式适用于那些有大量相似对象的场景。通过享元模式可以有效地优化内存的使用提高程序的性能。不过这种模式也会带来一定的复杂性需要根据具体场景权衡使用。 享元模式和单例模式对比 享元模式Flyweight Pattern和单例模式Singleton Pattern确实有一些相似之处但它们解决的问题和应用场景是不同的。以下是两者的主要区别 1. **目的不同** - **单例模式**的目的是**确保一个类只有一个实例**并提供全局访问点。它用于控制全局状态或资源访问的场景。例如日志管理器、配置管理器、线程池等通常使用单例模式。 - **享元模式**的目的是**通过共享多个相似对象来减少内存开销**。它用于大量相似对象的场景中主要目的是减少对象的数量优化内存使用。例如文字处理器中的字符对象、图形应用中的形状对象等。 2. **实现方式不同** - **单例模式**确保某个类只有一个实例通常通过私有构造函数和静态方法来实现。     public class Singleton {private static Singleton instance;private Singleton() { }public static Singleton getInstance() {if (instance null) {instance new Singleton();}return instance;}} - **享元模式**则通过工厂方法返回共享的对象实例。这个工厂方法会管理实例的创建和共享。    public class FlyweightFactory {private MapString, Flyweight flyweightMap new HashMap();public Flyweight getFlyweight(String key) {if (!flyweightMap.containsKey(key)) {flyweightMap.put(key, new ConcreteFlyweight(key));}return flyweightMap.get(key);}} 3. **应用场景不同** - **单例模式**适用于那些需要全局唯一的对象比如配置管理类、连接池等。 - **享元模式**适用于那些需要大量相似对象的场景比如文字处理、游戏开发中的图形元素等。它通过共享对象避免了创建大量相似的对象。 4. **实例数量** - **单例模式**限制一个类只能有**一个实例**整个应用程序中共享这一个实例。 - **享元模式**允许创建多个实例但这些实例是**有限的**并且**共享使用**。比如例子里的字符类是可以有多个实例的。 5. **状态管理** - **单例模式**通常管理的是全局的、不可变的状态。 - **享元模式**将对象的状态分为**内部状态**和**外部状态**。内部状态是共享的外部状态可以由客户端来传递或管理。 举个例子 - **单例模式**假设我们有一个日志管理器整个系统中只需要一个日志管理器实例来写日志。这个日志管理器就可以使用单例模式来实现。 - **享元模式**假设我们在开发一款游戏其中有许多树木对象每棵树的种类、颜色是相同的但它们的位置不同。我们可以使用享元模式来共享树的种类和颜色而位置则由外部传入。 ### 总结 - **单例模式**强调的是一个类只有一个实例全局共享该实例。 - **享元模式**强调的是共享对象通过共享相同的对象实例来减少内存消耗。 两者虽然都有“共享”的概念但其目的是不同的一个是为了控制实例数量另一个是为了优化资源使用。 行为型设计模式
http://www.w-s-a.com/news/685080/

相关文章:

  • 河北省建设厅网站重新安装优秀中文网页设计
  • 如何在腾讯云做网站开源站群cms
  • 公司网站建设的意义网易做网站
  • 网络营销案例分析与实践搜外seo
  • 手机建网站挣钱吗wordpress面包屑
  • 淘客做网站怎么备案网站开发工具的是什么
  • 提供大良网站建设郑州网站建设网站开发
  • 邢台做wap网站价格wordpress评论滑动
  • 绝味鸭脖网站建设规划书江苏建设人才网 官网
  • 网站源码授权破解centos wordpress 整站
  • 建设一个私人视频网站wordpress js
  • 手机企业网站制作流程3d建模自学
  • 网站优化方案和实施wordpress的归档
  • 建设事业单位网站多少钱集艾设计公司官网
  • 网站建设与管理方案书图片的制作方法
  • 中文建网站美发网站模板带手机版
  • 免费聊天不充值软件windows优化大师下载安装
  • 网站优化的关键词自己怎么做外贸网站空间
  • 现在建设的网站有什么劣势温州互联网公司
  • 重庆自助企业建站模板淘宝关键词top排行榜
  • 平邑网站制作买高端品牌网站
  • 深圳建网站三千网站安全代维
  • 西宁市精神文明建设网站装饰设计甲级资质
  • 做教育行业营销类型的网站徐州做网站多少钱
  • 临沂品牌网站制作企业网站建设搜集资料
  • wordpress注册验证码手机网站优化
  • 往建设厅网站上传东西做衣服的教程网站有哪些
  • 网上商城网站设计免费咨询口腔科医生回答在线
  • 南京网站c建设云世家 s浏览器
  • 如何做镜像别人网站wordpress菜单对齐修改