工厂设计模式

        工厂设计模式是一种广泛使用的创建型设计模式,它的核心思想是定义一个用于创建对象的接口,让子类决定实例化哪一个类。这种模式可以使代码更具灵活性和可扩展性,尤其在面对复杂对象结构和大量类需要实例化时,能够降低耦合度和提高程序的组织结构。

工厂模式主要包括以下几种实现方式:

   1、简单工厂模式(Simple Factory Pattern / Static Factory Method)                                
        在Java中实现简单工厂模式(Simple Factory Pattern),我们通常创建一个工厂类,该类包含静态方法来决定并创建所需的对象。以下是一个简单工厂模式的示例,我们将创建一个披萨店,可以制作多种口味的披萨:

首先,我们定义一个抽象披萨类(Pizza):

public abstract class Pizza {
    public abstract void prepare();
    public abstract void bake();
    public abstract void cut();
    public abstract void box();
    
    public void deliver() {
        System.out.println("Delivering the pizza now...");
    }
}

然后,我们创建几种具体口味的披萨类继承自抽象披萨类:

public class CheesePizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println("Preparing cheese pizza...");
    }

    // ... 实现其他方法
}

public class PepperoniPizza extends Pizza {
    @Override
    public void prepare() {
        System.out.println("Preparing pepperoni pizza...");
    }

    // ... 实现其他方法
}

接下来,创建一个披萨工厂类(PizzaStore):

public class PizzaStore {
    public static Pizza orderPizza(String type) {
        Pizza pizza = null;

        if ("cheese".equals(type)) {
            pizza = new CheesePizza();
        } else if ("pepperoni".equals(type)) {
            pizza = new PepperoniPizza();
        } else {
            System.out.println("Sorry, we don't make that kind of pizza yet.");
            return null;
        }

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;
    }
}

最后,客户端代码可以通过工厂类下单并制作披萨:

public class Client {
    public static void main(String[] args) {
        Pizza pizza = PizzaStore.orderPizza("cheese");
        pizza.deliver();

        pizza = PizzaStore.orderPizza("pepperoni");
        pizza.deliver();
    }
}

        在这个例子中,PizzaStore 类就是简单工厂,它根据传入的类型参数("cheese" 或 "pepperoni")创建相应的披萨对象。客户端只需调用 orderPizza 方法,无需了解具体的披萨制作过程。

       优点:隐藏了创建产品的具体逻辑,简化了客户端代码。
       缺点:违背开闭原则,每当增加新产品时需要修改工厂类的代码

2、工厂方法模式(Factory Method Pattern)

        定义一个工厂接口(或抽象类),在其子类中实现具体的产品创建逻辑。  客户端通过调用工厂接口的通用方法来获得所需的产品对象。

        以下是工厂方法模式的一个简单示例,我们还是以披萨店为例,这次我们将创建一个抽象披萨店,具体披萨店负责制作不同口味的披萨:

        首先,我们保留之前的抽象披萨类(Pizza)不变:

public abstract class Pizza {
    public abstract void prepare();
    public abstract void bake();
    public abstract void cut();
    public abstract void box();
    
    public void deliver() {
        System.out.println("Delivering the pizza now...");
    }
}

然后,我们仍然有各种口味的具体披萨类:

public class CheesePizza extends Pizza {
    // ... 实现方法
}

public class PepperoniPizza extends Pizza {
    // ... 实现方法
}

接下来,我们创建一个抽象披萨店类(AbstractPizzaStore),包含一个工厂方法:

public abstract class AbstractPizzaStore {
    public Pizza orderPizza(String type) {
        Pizza pizza = createPizza(type);
        
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        
        return pizza;
    }
    
    protected abstract Pizza createPizza(String type);
}

接着,我们创建具体披萨店类继承自抽象披萨店类,并实现工厂方法:

public class NYPizzaStore extends AbstractPizzaStore {
    @Override
    protected Pizza createPizza(String type) {
        if ("cheese".equals(type)) {
            return new NYCheesePizza();
        } else if ("pepperoni".equals(type)) {
            return new NYPepperoniPizza();
        } else {
            return null;
        }
    }
}

// 类似地,可以创建ChicagoPizzaStore,对应芝加哥风味的披萨

最后,客户端代码通过具体披萨店下单并制作披萨:

public class Client {
    public static void main(String[] args) {
        AbstractPizzaStore nyStore = new NYPizzaStore();
        Pizza pizza = nyStore.orderPizza("cheese");
        pizza.deliver();

        pizza = nyStore.orderPizza("pepperoni");
        pizza.deliver();
    }
}

        在这个例子中,NYPizzaStore 类实现了 AbstractPizzaStore 的 createPizza 方法,即工厂方法,根据传入的披萨类型创建相应的披萨对象。这样,每个具体的披萨店子类都可以定制自己的披萨品种,而抽象披萨店则负责统一的订单流程。
        优点:很好地支持了开闭原则,扩展新产品时无需修改原有的工厂类,只需要新增一个实现工厂接口的子类。
        缺点:随着产品类的增多,可能会有大量的工厂类。

3、抽象工厂模式(Abstract Factory Pattern)

        提供一个接口,用于创建相关或依赖对象家族的一系列相关或相互依赖的对象,而不指定具体的产品类。适合于一个产品族内的多个产品对象都需要一起创建的情况。

        以下是抽象工厂模式的一个简单示例,我们继续沿用披萨店的例子,这次不仅要生产不同口味的披萨,还要区分纽约风格和芝加哥风格的披萨原料:

首先,我们依然保留抽象披萨类(Pizza)和具体口味的披萨类:

public abstract class Pizza {
    // ... 共享的方法实现
}

public class NYStyleCheesePizza extends Pizza {
    // ... 纽约风格奶酪披萨特有的实现
}

public class ChicagoStyleCheesePizza extends Pizza {
    // ... 芝加哥风格奶酪披萨特有的实现
}

// 同样地,创建其他具体口味的披萨类

然后,我们创建一个抽象原料工厂接口:

public interface PizzaIngredientFactory {
    Dough createDough();
    Sauce createSauce();
    Cheese createCheese();
    // ... 其他原料的创建方法
}

接下来,我们创建两个具体原料工厂类,分别对应纽约风格和芝加哥风格:

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
    @Override
    public Dough createDough() {
        return new ThinCrustDough(); // 假设纽约风格披萨用薄底面团
    }

    // ... 实现其他原料的创建方法
}

public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
    @Override
    public Dough createDough() {
        return new DeepDishDough(); // 假设芝加哥风格披萨用深盘面团
    }

    // ... 实现其他原料的创建方法
}

最后,我们创建一个抽象披萨店类,并关联原料工厂:

public abstract class AbstractPizzaStore {
    protected PizzaIngredientFactory ingredientFactory;

    public AbstractPizzaStore(PizzaIngredientFactory ingredientFactory) {
        this.ingredientFactory = ingredientFactory;
    }

    public Pizza orderPizza(String type) {
        Pizza pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }

    protected abstract Pizza createPizza(String type);
}

再创建具体披萨店类,实现抽象披萨店的 createPizza 方法,并关联相应的原料工厂:

public class NYPizzaStore extends AbstractPizzaStore {
    public NYPizzaStore() {
        super(new NYPizzaIngredientFactory());
    }

    @Override
    protected Pizza createPizza(String type) {
        if ("cheese".equals(type)) {
            return new NYStyleCheesePizza(ingredientFactory);
        } // ... 其他口味的披萨创建
    }
}

// 同样创建ChicagoPizzaStore类

客户端代码通过具体披萨店下单并制作披萨,同时隐含选择了原料工厂:

public class Client {
    public static void main(String[] args) {
        AbstractPizzaStore nyStore = new NYPizzaStore();
        Pizza pizza = nyStore.orderPizza("cheese");
        pizza.deliver();

        // 创建芝加哥风格披萨店并下单
        // ...
    }
}

        在这个例子中,抽象工厂模式允许客户端通过选择不同的披萨店(即具体工厂)来决定生产何种风格的披萨(产品),同时披萨的原料也是由选定的工厂提供的,体现了工厂之间的关联和产品族的概念。
        优点:更加灵活,有助于分隔组件的独立性和减少依赖关系,方便更换整体的产品族。
        缺点:增加了系统的复杂度,更多的类和接口需要维护。

        工厂模式的主要用途在于解耦,使得代码更容易维护和扩展,可以根据配置信息或其他条件灵活地创建不同类型的对象,而客户端不必知道具体的实现细节。在实际开发中,工厂模式常常与其他设计模式相结合,以更好地适应复杂的设计需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值