深入理解软件设计模式中的工厂模式与策略模式

风吹过的夏天 2020-04-20 ⋅ 14 阅读

在软件设计中,设计模式是一种被广泛接受和应用的设计思想和方法。其中,工厂模式和策略模式是两个常用且重要的设计模式。它们都可以帮助我们提高代码的可维护性、灵活性和可扩展性。本文将深入探讨工厂模式与策略模式的内涵和应用场景。

工厂模式

工厂模式是一种创建型设计模式,其主要目的是封装对象的创建过程并将其交给一个工厂类负责。工厂模式可以根据不同的条件或参数来创建出不同类型的对象,使得客户端代码与具体对象的创建相分离。

简单工厂模式

简单工厂模式是工厂模式的一种最基本形式,它由一个工厂类负责创建对象,并通过一个标识参数来判断要创建的对象类型。这种模式适用于创建对象较少而且类型固定的情况。

public class SimpleFactory {
    public static Product createProduct(String type) {
        if (type.equals("A")) {
            return new ProductA();
        } else if (type.equals("B")) {
            return new ProductB();
        } else if (type.equals("C")) {
            return new ProductC();
        } else {
            throw new IllegalArgumentException("Invalid product type.");
        }
    }
}

简单工厂模式的优点是简单易懂,客户端只需要知道要创建的对象类型,而不需要关心具体的创建细节。然而,它的缺点也很明显,当需要新增一个产品类型时,工厂类的代码就需要修改,不符合开闭原则。

工厂方法模式

工厂方法模式是一种更加抽象和灵活的工厂模式,它将对象的创建过程抽象成一个工厂接口,并由多个具体的工厂类实现该接口以创建不同类型的对象。这样,客户端只需要通过工厂接口来创建对象,而无需关心具体的创建逻辑。

public interface Factory {
    Product createProduct();
}

public class ConcreteFactoryA implements Factory {
    public Product createProduct() {
        return new ProductA();
    }
}

public class ConcreteFactoryB implements Factory {
    public Product createProduct() {
        return new ProductB();
    }
}

工厂方法模式的优点是符合开闭原则,当需要新增一个产品类型时,只需要新增一个对应的工厂类即可,不需要修改已有的代码。缺点是客户端需要知道具体的工厂类,增加了客户端的复杂度。

抽象工厂模式

抽象工厂模式进一步提高了工厂的抽象程度,它可以用于创建一组相关的产品对象。抽象工厂模式由一个抽象工厂接口定义,每个具体的工厂类负责创建相关产品族的对象。

public interface AbstractFactory {
    Product createProduct();
    AnotherProduct createAnotherProduct();
}

public class ConcreteFactory implements AbstractFactory {
    public Product createProduct() {
        return new ConcreteProduct();
    }
    
    public AnotherProduct createAnotherProduct() {
        return new ConcreteAnotherProduct();
    }
}

抽象工厂模式的优点是可以创建一组相关的产品对象,使得客户端更加灵活地使用不同的产品。缺点是难以扩展新的产品族,需要修改已有的工厂接口和实现类。

策略模式

策略模式是一种行为型设计模式,它定义了一系列算法,并将每个算法封装成一个具体的策略类。这样,客户端可以在运行时选择不同的策略来解决问题,而无需修改客户端的代码。

策略模式的结构

策略模式的核心思想是将算法独立于客户端而存在,并使用策略接口来统一调用不同的策略。策略模式的结构包括:

  • 策略接口(Strategy):定义了算法的统一调用接口。
  • 具体策略类(ConcreteStrategy):实现了策略接口,封装了具体的算法。
  • 环境类(Context):维护一个对策略对象的引用,提供一个统一的调用接口。
public interface Strategy {
    void doSomething();
}

public class ConcreteStrategyA implements Strategy {
    public void doSomething() {
        // 实现具体的算法A
    }
}

public class ConcreteStrategyB implements Strategy {
    public void doSomething() {
        // 实现具体的算法B
    }
}

public class Context {
    private Strategy strategy;
    
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    
    public void execute() {
        strategy.doSomething();
    }
}

策略模式的应用

策略模式适用于需要在运行时动态选择算法的情况,它可以提高代码的灵活性和可维护性。例如,一个商场的收银系统可以使用策略模式来实现不同的优惠策略。

public interface DiscountStrategy {
    double applyDiscount(double price);
}

public class NoDiscountStrategy implements DiscountStrategy {
    public double applyDiscount(double price) {
        return price;
    }
}

public class TenPercentDiscountStrategy implements DiscountStrategy {
    public double applyDiscount(double price) {
        return price * 0.9;
    }
}

public class Context {
    private DiscountStrategy strategy;
    
    public Context(DiscountStrategy strategy) {
        this.strategy = strategy;
    }
    
    public double calculate(double price) {
        return strategy.applyDiscount(price);
    }
}

在商场的收银系统中,可以根据不同的场景选择不同的优惠策略:

Context context = new Context(new TenPercentDiscountStrategy());
double totalPrice = context.calculate(100.0);

总结

工厂模式和策略模式都是常用的设计模式,它们都能提供灵活性和可维护性。工厂模式封装了对象的创建过程,并实现了一定程度的解耦;而策略模式则将算法的选择与客户端代码相分离,使得算法能够独立于客户端变化。在实际的软件设计中,我们可以根据实际需求选择合适的设计模式来提高代码的可扩展性和可维护性。


全部评论: 0

    我有话说: