13设计模式

178 阅读7分钟

设计模式

说下了解的设计模式和应用场景 7.详细说下工厂模式

​ 设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。

设计模式分类

  • 创建型模式,共五种:工厂方法模式、抽象工厂模式单例模式、建造者模式、原型模式。
  • 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

单例模式 +3

单例模式是一种常见的设计模式,它保证一个类只有一个实例,并提供一个全局访问点。

实现单例模式的方法有很多种,下面介绍两种比较常见的方法:

  1. 懒汉式单例模式

懒汉式单例模式是指在第一次使用时才创建单例对象的方式。具体实现方式可以如下:

javaCopy codepublic class Singleton {
    private static Singleton instance;
    
    private Singleton() {}
    
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

这种方式的优点是在单例对象第一次使用时才会创建,可以节省系统资源。但是在多线程环境下,需要使用 synchronized 关键字保证线程安全,可能会导致性能问题。

2.饿汉式单例模式

饿汉式单例模式是指在类加载时就创建单例对象的方式。具体实现方式可以如下:

javaCopy codepublic class Singleton {
    private static Singleton instance = new Singleton();
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        return instance;
    }
}

这种方式的优点是不需要使用 synchronized 关键字保证线程安全,可以避免性能问题。但是在类加载时就创建单例对象,可能会浪费系统资源。

除了以上两种方式,还有其他实现单例模式的方式,比如枚举类实现、静态内部类实现等。

单例模式的应用场景很多,比如线程池、数据库连接池、windows的任务管理器等。

简单工厂、工厂方法、抽象工厂模式 +2

简单工厂模式、工厂方法模式、抽象工厂模式均属于创建型设计模式,都是用来创建对象的。它们的主要区别在于创建对象的方式和级别不同。

  1. 简单工厂模式

简单工厂模式又称为静态工厂方法模式,它通过一个工厂类来创建一个产品类的实例,而无需直接使用new实例化。简单工厂模式一般包括三种角色:工厂角色、抽象产品角色和具体产品角色。其中,工厂角色负责实现创建具体产品对象的内部逻辑,抽象产品角色负责定义产品的接口,具体产品角色则实现抽象产品接口。

举个例子,我们可以设计一个汽车工厂来生产不同类型的汽车:

javaCopy codepublic interface Car {
    void run();
}

public class BenzCar implements Car {
    @Override
    public void run() {
        System.out.println("Benz Car is running.");
    }
}

public class BmwCar implements Car {
    @Override
    public void run() {
        System.out.println("Bmw Car is running.");
    }
}

public class CarFactory {
    public static Car createCar(String carType) {
        Car car;
        switch (carType) {
            case "Benz":
                car = new BenzCar();
                break;
            case "Bmw":
                car = new BmwCar();
                break;
            default:
                car = null;
                break;
        }
        return car;
    }
}

public class Client {
    public static void main(String[] args) {
        Car car = CarFactory.createCar("Benz");
        car.run();
    }
}
  1. 工厂方法模式

工厂方法模式又称为多态性工厂模式,它通过定义一个用于创建对象的接口,让子类来决定实例化哪一个类。工厂方法模式一般包括四种角色:抽象工厂角色、具体工厂角色、抽象产品角色和具体产品角色。

每个具体工厂生产一种具体产品

举个例子,我们可以设计一个手机工厂来生产不同品牌的手机:

javaCopy codepublic interface Phone {
    void call();
}

public class Iphone implements Phone {
    @Override
    public void call() {
        System.out.println("Iphone is calling.");
    }
}

public class Huawei implements Phone {
    @Override
    public void call() {
        System.out.println("Huawei is calling.");
    }
}

public interface PhoneFactory {
    Phone createPhone();
}

public class IphoneFactory implements PhoneFactory {
    @Override
    public Phone createPhone() {
        return new Iphone();
    }
}

public class HuaweiFactory implements PhoneFactory {
    @Override
    public Phone createPhone() {
        return new Huawei();
    }
}

public class Client {
    public static void main(String[] args) {
        PhoneFactory factory = new IphoneFactory();
        Phone phone = factory.createPhone();
        phone.call();
    }
}

3.抽象工厂模式

抽象工厂模式是一种创建型设计模式,它提供了一种封装一组具有相同主题的独立工厂的方式,而不需要指定其具体类。

在抽象工厂模式中,抽象工厂定义了可以创建一组相关对象的方法,而这些对象在一个具体的实现类中被实例化。这样可以使得系统更加灵活,因为可以方便地替换工厂的具体实现类,从而改变系统的行为。

抽象工厂模式与工厂方法模式类似,但是它不仅仅创建一个对象,而是一组对象。抽象工厂通常使用多个工厂方法创建一组对象,而工厂方法只创建一个对象。因此,抽象工厂模式是工厂方法模式的扩展。

使用抽象工厂模式的一个经典场景是在 UI 设计中,不同的操作系统有不同的 UI 风格。例如,Windows 和 Mac OS X 的按钮在外观上是不同的。在这种情况下,可以使用抽象工厂模式来创建一个抽象的 UI 工厂,然后根据当前操作系统的类型,使用不同的具体工厂来创建 UI 元素。这样,即使在不同的操作系统中,UI 元素也可以保持一致的风格。

// 抽象工厂
interface AbstractFactory {
    Button createButton();
    TextField createTextField();
}

// 具体工厂 - Windows 样式
class WindowsFactory implements AbstractFactory {
    public Button createButton() {
        return new WindowsButton();
    }

    public TextField createTextField() {
        return new WindowsTextField();
    }
}

// 具体工厂 - Mac 样式
class MacFactory implements AbstractFactory {
    public Button createButton() {
        return new MacButton();
    }

    public TextField createTextField() {
        return new MacTextField();
    }
}

// 抽象产品 - 按钮
interface Button {
    void click();
}

// 具体产品 - Windows 按钮
class WindowsButton implements Button {
    public void click() {
        System.out.println("Windows button clicked.");
    }
}

// 具体产品 - Mac 按钮
class MacButton implements Button {
    public void click() {
        System.out.println("Mac button clicked.");
    }
}

// 抽象产品 - 文本框
interface TextField {
    void input();
}

// 具体产品 - Windows 文本框
class WindowsTextField implements TextField {
    public void input() {
        System.out.println("Windows text field input.");
    }
}

// 具体产品 - Mac 文本框
class MacTextField implements TextField {
    public void input() {
        System.out.println("Mac text field input.");
    }
}

// 客户端代码
class Client {
    public static void main(String[] args) {
        // 根据当前操作系统类型选择工厂
        AbstractFactory factory;
        String osName = System.getProperty("os.name").toLowerCase();
        if (osName.contains("

代理模式

好的,以下是一个简单的代理模式的示例代码:

csharpCopy code// 接口定义
interface Calculator {
    public int add(int a, int b);
    public int sub(int a, int b);
}

// 真实的计算器实现
class RealCalculator implements Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    public int sub(int a, int b) {
        return a - b;
    }
}

// 代理类
class CalculatorProxy implements Calculator {
    private RealCalculator calculator;
    public CalculatorProxy() {
        calculator = new RealCalculator();
    }
    public int add(int a, int b) {
        // 做一些额外的处理
        System.out.println("Proxy: Before add operation");
        int result = calculator.add(a, b);
        System.out.println("Proxy: After add operation");
        // 做一些额外的处理
        return result;
    }
    public int sub(int a, int b) {
        // 做一些额外的处理
        System.out.println("Proxy: Before sub operation");
        int result = calculator.sub(a, b);
        System.out.println("Proxy: After sub operation");
        // 做一些额外的处理
        return result;
    }
}

// 使用代理类进行计算
public class Main {
    public static void main(String[] args) {
        Calculator calculator = new CalculatorProxy();
        int result1 = calculator.add(1, 2);
        System.out.println("Result1: " + result1);
        int result2 = calculator.sub(5, 3);
        System.out.println("Result2: " + result2);
    }
}

在上面的代码中,我们定义了一个 Calculator 接口,它有两个方法 addsub,表示加法和减法运算。我们在 RealCalculator 类中实现了这个接口,并且真正地进行了加减运算。然后我们创建了一个代理类 CalculatorProxy,它也实现了 Calculator 接口,并且在内部持有了一个真正的计算器对象 RealCalculator。当我们在代理类中调用 addsub 方法时,它会在调用真正的计算器对象之前和之后,做一些额外的处理。这些额外的处理可以是日志记录、权限验证等等。在 Main 类中,我们创建了一个代理对象,并且使用它进行了两次加减运算。通过代理类的包装,我们可以在不修改原有计算器实现的情况下,为其增加一些额外的功能,同时也保持了原有代码的简洁性和可维护性。

  1. 简单工厂和抽象工厂的区别:
  2. 抽象工厂模式用在什么地方。
  3. 用过什么设计模式 答代理

我看你有了解设计模式,项目哪里用了设计模式,为什么要用?