UML 的工厂方法设计模式 策略设计模式 抽象工厂设计模式 观察者设计模式

发布于:2024-04-28 ⋅ 阅读:(32) ⋅ 点赞:(0)

UML 的工厂方法设计模式

UML 的工厂方法设计模式是一种创建型设计模式,它通过定义一个创建对象的接口,但将具体的对象创建延迟到子类中。这样可以让子类决定实例化哪个类。该模式提供了一种创建对象的灵活方式,同时也隐藏了对象的具体实现细节。

下面通过一个示例来说明工厂方法模式的应用。

假设我们正在开发一个游戏,需要创建不同类型的角色,包括战士、法师和射手。我们可以使用工厂方法模式来创建这些角色对象。

首先,定义一个抽象的角色类 Character,其中包含一个抽象的方法 attack()

public abstract class Character {
    public abstract void attack();
}

然后,定义具体的角色类,继承自抽象角色类,并实现 attack() 方法:

public class Warrior extends Character {
    @Override
    public void attack() {
        System.out.println("Warrior attacks with a sword!");
    }
}

public class Mage extends Character {
    @Override
    public void attack() {
        System.out.println("Mage attacks with magic spells!");
    }
}

public class Archer extends Character {
    @Override
    public void attack() {
        System.out.println("Archer attacks with a bow and arrows!");
    }
}

接下来,定义一个抽象的角色工厂类 CharacterFactory,其中包含一个抽象的工厂方法 createCharacter()

public abstract class CharacterFactory {
    public abstract Character createCharacter();
}

然后,定义具体的角色工厂类,继承自抽象角色工厂类,并实现 createCharacter() 方法来创建具体的角色对象:

public class WarriorFactory extends CharacterFactory {
    @Override
    public Character createCharacter() {
        return new Warrior();
    }
}

public class MageFactory extends CharacterFactory {
    @Override
    public Character createCharacter() {
        return new Mage();
    }
}

public class ArcherFactory extends CharacterFactory {
    @Override
    public Character createCharacter() {
        return new Archer();
    }
}

最后,客户端代码可以通过调用工厂方法来创建不同类型的角色对象:

public class Client {
    public static void main(String[] args) {
        CharacterFactory warriorFactory = new WarriorFactory();
        Character warrior = warriorFactory.createCharacter();
        warrior.attack();

        CharacterFactory mageFactory = new MageFactory();
        Character mage = mageFactory.createCharacter();
        mage.attack();

        CharacterFactory archerFactory = new ArcherFactory();
        Character archer = archerFactory.createCharacter();
        archer.attack();
    }
}

这样,客户端只需要通过调用工厂方法来获取角色对象,并调用其方法来进行相应的操作,而无需关心具体的角色创建细节。

UML的策略设计模式

策略设计模式是一种行为型设计模式,它定义了一系列算法或行为,将每个算法或行为封装在独立的类中,并使它们可以互相替换。通过使用策略模式,客户端可以在运行时选择不同的策略来完成相同的任务,而不需要更改客户端的代码。

策略模式通过将不同行为封装成独立的策略类,每个策略类实现一个共同的接口或抽象类。然后在客户端代码中,通过选择具体的策略对象来改变对象的行为。

下面通过一个示例来说明策略模式的应用。

假设我们正在开发一个电商平台,需要根据不同地区的运输方式计算订单的运费。我们可以使用策略模式来实现不同的运费计算策略。

首先,定义一个抽象的运费计算策略接口 ShippingStrategy

public interface ShippingStrategy {
    double calculate(double originalPrice);
}

然后,定义具体的运费计算策略类,实现 ShippingStrategy 接口:

public class StandardShippingStrategy implements ShippingStrategy {
    @Override
    public double calculate(double originalPrice) {
        // 标准运输方式的运费计算逻辑
        return originalPrice * 0.1;
    }
}

public class ExpressShippingStrategy implements ShippingStrategy {
    @Override
    public double calculate(double originalPrice) {
        // 快递运输方式的运费计算逻辑
        return originalPrice * 0.2;
    }
}

public class FreeShippingStrategy implements ShippingStrategy {
    @Override
    public double calculate(double originalPrice) {
        // 免运费运输方式的运费计算逻辑
        return 0.0;
    }
}

接下来,定义一个电商订单类 Order,其中包含一个运费计算策略对象和一个计算运费的方法:

public class Order {
    private ShippingStrategy shippingStrategy;

    public Order(ShippingStrategy shippingStrategy) {
        this.shippingStrategy = shippingStrategy;
    }

    public double calculateShippingFee(double originalPrice) {
        return shippingStrategy.calculate(originalPrice);
    }
}

最后,在客户端代码中,根据需要选择具体的运费计算策略进行计算:

public class Client {
    public static void main(String[] args) {
        ShippingStrategy standardShippingStrategy = new StandardShippingStrategy();
        Order order1 = new Order(standardShippingStrategy);
        double fee1 = order1.calculateShippingFee(100.0);
        System.out.println("Standard shipping fee: " + fee1);

        ShippingStrategy expressShippingStrategy = new ExpressShippingStrategy();
        Order order2 = new Order(expressShippingStrategy);
        double fee2 = order2.calculateShippingFee(100.0);
        System.out.println("Express shipping fee: " + fee2);

        ShippingStrategy freeShippingStrategy = new FreeShippingStrategy();
        Order order3 = new Order(freeShippingStrategy);
        double fee3 = order3.calculateShippingFee(100.0);
        System.out.println("Free shipping fee: " + fee3);
    }
}

这样,客户端可以根据需要选择不同的运费计算策略,并通过订单对象的方法进行运费计算。

UML的抽象工厂设计模式

抽象工厂设计模式是一种创建型设计模式,它提供了一种创建一系列相关或依赖对象的接口,而无需指定具体类。它主要解决的问题是如何创建一组具有共同特征的对象。

抽象工厂模式通过引入抽象工厂接口和具体工厂实现类,以及一系列相关的产品接口和具体产品实现类,来实现对象的创建。

下面通过一个示例来说明抽象工厂模式的应用。

假设我们正在开发一个跨平台的图形界面库,需要支持 Windows 和 Mac 两个操作系统的界面风格。我们可以使用抽象工厂模式来实现不同操作系统下的界面组件的创建。

首先,定义抽象的界面组件接口 ButtonTextbox

public interface Button {
    void render();
}

public interface Textbox {
    void render();
}

然后,在每个操作系统下,定义具体的界面组件实现类:

// Windows操作系统下的界面组件实现类
public class WindowsButton implements Button {
    @Override
    public void render() {
        // Windows风格的按钮渲染逻辑
        System.out.println("Rendering Windows button...");
    }
}

public class WindowsTextbox implements Textbox {
    @Override
    public void render() {
        // Windows风格的文本框渲染逻辑
        System.out.println("Rendering Windows textbox...");
    }
}

// Mac操作系统下的界面组件实现类
public class MacButton implements Button {
    @Override
    public void render() {
        // Mac风格的按钮渲染逻辑
        System.out.println("Rendering Mac button...");
    }
}

public class MacTextbox implements Textbox {
    @Override
    public void render() {
        // Mac风格的文本框渲染逻辑
        System.out.println("Rendering Mac textbox...");
    }
}

接下来,定义抽象工厂接口 GUIFactory,其中包含创建按钮和文本框的方法:

public interface GUIFactory {
    Button createButton();
    Textbox createTextbox();
}

然后,在每个操作系统下,定义具体的工厂实现类,分别实现 GUIFactory 接口:

// Windows操作系统下的界面组件工厂
public class WindowsGUIFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }

    @Override
    public Textbox createTextbox() {
        return new WindowsTextbox();
    }
}

// Mac操作系统下的界面组件工厂
public class MacGUIFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }

    @Override
    public Textbox createTextbox() {
        return new MacTextbox();
    }
}

最后,在客户端代码中,根据当前操作系统选择合适的工厂,并使用工厂创建界面组件:

public class Client {
    public static void main(String[] args) {
        // 根据操作系统选择合适的工厂
        GUIFactory factory;
        if (isWindows()) {
            factory = new WindowsGUIFactory();
        } else {
            factory = new MacGUIFactory();
        }

        // 使用工厂创建界面组件
        Button button = factory.createButton();
        Textbox textbox = factory.createTextbox();

        // 使用界面组件
        button.render();
        textbox.render();
    }

    private static boolean isWindows() {
        // 判断当前操作系统是否为Windows
        // ...
        return true;
    }
}

这样,通过选择合适的工厂,可以在不同的操作系统下创建对应的界面组件,并使用这些界面组件进行开发。

UML的观察者设计模式

观察者设计模式是一种行为型设计模式,它定义了对象之间的一种一对多的依赖关系,使得当一个对象状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

在观察者模式中,有两个关键角色:观察者(Observer)和被观察者(Subject)。观察者订阅被观察者,当被观察者状态发生变化时,观察者会收到通知并执行相应的操作。

下面通过一个示例来说明观察者模式的应用。

假设有一个电子商务网站,当某个商品降价时,网站上的用户应该能够自动收到相关的通知。

首先,定义观察者接口 Observer,其中包含一个更新通知的方法:

public interface Observer {
    void update(String message);
}

然后,定义被观察者类 Product,其中包含订阅、取消订阅和通知观察者的方法:

import java.util.ArrayList;
import java.util.List;

public class Product {
    private List<Observer> observers = new ArrayList<>();
    private String name;
    private double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public void attach(Observer observer) {
        observers.add(observer);
    }

    public void detach(Observer observer) {
        observers.remove(observer);
    }

    public void setPrice(double price) {
        if (this.price != price) {
            this.price = price;
            notifyObservers();
        }
    }

    private void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(name + " 的价格已经改变为 " + price);
        }
    }
}

接下来,定义观察者类 User,该类实现了 Observer 接口,当收到通知时会打印相关信息:

public class User implements Observer {
    private String name;

    public User(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " 收到通知:" + message);
    }
}

最后,在客户端代码中,创建被观察者对象和观察者对象,并建立订阅关系:

public class Client {
    public static void main(String[] args) {
        // 创建被观察者对象
        Product product = new Product("手机", 2000.0);

        // 创建观察者对象
        Observer user1 = new User("张三");
        Observer user2 = new User("李四");

        // 建立订阅关系
        product.attach(user1);
        product.attach(user2);

        // 改变被观察者状态,触发通知

这些设计模式在软件开发中都有广泛的应用,可以提供灵活的解决方案来实现各种需求。在使用它们时需要根据实际情况选择最合适的设计模式,并根据设计原则和模式的特性来进行设计和实现。