设计模式之工厂模式

单例模式是我最初认识的设计模式,工厂模式呢是我最初使用的设计模式。
工厂模式分为三种:简单工厂模式,工厂模式,抽象工厂模式
以前一直不清楚这三种工厂模式的区别,在系统的学习后终于明白了。

    简单工厂模式:其实也不算设计模式,它更像是一种编程习惯。只是多了一个工厂类来实例化产品对象,客户类并不需要知道具体调用哪个产品类,只需要调用工厂类去实例化产品对象就好。
    工厂模式:定义一个创建对象的接口,有子类确定实例化的类是哪一个,工厂模式让类把实例化推迟给子类。
    抽象工厂模式:用于创建一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

强行理解概念很容易绕晕自己,就简单的举个例子吧:
    比如你要开一家披萨店,里面有芝士披萨、海鲜披萨等,这个时候可以使用简单工厂模式:写一个工厂类去实例化产品类,即一个披萨工厂类实例化各种口味的披萨;
    如果你要开两家披萨店,一家是纽约风味,一家是芝加哥风味的,这个时候可以使用工厂模式:一个是纽约披萨工厂类,一个是芝加哥披萨工厂类。工厂模式与简单工厂模式的不同是:工厂模式抽象出工厂类,可以有多个工厂继承抽象工厂类。
    当你需要统一管理披萨的原材料,例如披萨面饼、酱料等,可以使用抽象工厂模式:面饼工厂类,实例化纽约披萨面饼、芝加哥披萨面饼,抽象工厂类与工厂类的不同是:抽象工厂实例化的产品类依赖于工厂类的产品类,比如,抽象工厂的面饼工厂类可以做纽约披萨面饼、芝加哥披萨面饼,这取决于披萨的需要。
(披萨的例子参考《Head First设计模式》这本书,下面的例子参考《Java与模式》这本书)

再简单的说个例子,如果你现在有一个小农场,里面种各种蔬菜,这个时候可以使用简单工厂模式:一个工厂类管理各种蔬菜;
你的农场开始扩建,种有各种蔬菜还有各种水果,这个时候可以使用工厂模式:一个蔬菜工厂类,一个水果工厂类;
现在你的农场越做越大,引入了热带水果以及热带蔬菜,这个时候就可以使用抽象工厂模式了。

好了,以下开始贴代码,首先是简单工厂的示例代码,第二部分是工厂模式的示例代码,最后是抽象工厂模式的示例代码。


简单工厂模式
先抽象出披萨类:

public abstract class Pizza {
    String name;
    String dough;
    String sauce;
    List<String> toppings = new ArrayList<>();
    abstract void prepare();
    void bake() {
        System.out.println("\n烘焙25-30min");
    }
    void cut() {
        System.out.println("将披萨切块");
    }
    void box() {
        System.out.println("将披萨装盒");
    }
    public String getName() {
        return name;
    }
}

纽约芝士披萨:

public class NYStyleCheesePizza extends Pizza {
    public NYStyleCheesePizza() {
        name = "纽约风味芝士披萨";
        dough = "纽约厚面饼";
        sauce = "纽约海鲜酱料";
        toppings.add("纽约风味--芝士");
    }
    @Override
    void prepare() {
        System.out.println("\n======================");
        System.out.println(name);
        System.out.println("制作:");
        System.out.println("    " + dough);
        System.out.println("    " + sauce);
        System.out.println("    调味品:");
        for (int i = 0; i < toppings.size(); i++) {
            System.out.println("         " + toppings.get(i));
        }
    }
}

纽约海鲜披萨:

public class NYStyleClamPizza extends Pizza {
    public NYStyleClamPizza() {
        name = "纽约风味海鲜披萨";
        dough = "纽约厚面饼";
        sauce = "纽约酱料";
        toppings.add("纽约风味--海鲜");
    }
    @Override
    void prepare() {
        System.out.println("\n======================");
        System.out.println(name);
        System.out.println("制作:");
        System.out.println("    " + dough);
        System.out.println("    " + sauce);
        System.out.println("    调料:");
        for (int i = 0; i < toppings.size(); i++) {
            System.out.println("         " + toppings.get(i));
        }
    }
}

最重要的工厂类:

public class PizzaStore {
    public Pizza orderPizza(String type) {
        Pizza pizza;
        pizza = creatPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
    public Pizza creatPizza(String type) {
        if ("cheese".equals(type)) {
            return new NYStyleCheesePizza();
        } else if ("clam".equals(type)) {
            return new NYStyleClamPizza();
        }
        return null;
    }
}

开始测试吧~

public class Test {
    public static void main(String[] args) {
        PizzaStore store = new PizzaStore();
        Pizza pizza = store.orderPizza("cheese");
        System.out.println("一号客人收到" + pizza.getName());
        Pizza pizza2 = store.orderPizza("clam");
        System.out.println("二号客人收到" + pizza2.getName());
    }
}

结果:
这里写图片描述


工厂模式
纽约披萨店的披萨与上面代码差不多,此处只贴芝加哥披萨店的披萨(芝加哥海鲜披萨):

public class ChicagoStyleClamPizza extends Pizza {
    public ChicagoStyleClamPizza() {
        name = "芝加哥风味海鲜披萨";
        dough = "芝加哥薄面饼";
        sauce = "芝加哥海鲜酱料";
        toppings.add("芝加哥风味--海鲜");
    }
    void cut() {
        System.out.println("芝加哥披萨切成正方形");
    }
    @Override
    void prepare() {
        System.out.println("\n======================");
        System.out.println(name);
        System.out.println("制作:");
        System.out.println("    " + dough);
        System.out.println("    " + sauce);
        System.out.println("    调料:");
        for (int i = 0; i < toppings.size(); i++) {
            System.out.println("         " + toppings.get(i));
        }
    }
}

披萨工厂抽象类:

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

纽约披萨工厂类:

public class NYPizzaFactory extends PizzaStore {
    @Override
    Pizza creatPizza(String type) {
        if ("cheese".equals(type)) {
            return new NYStyleCheesePizza();
        }else if("clam".equals(type)){
            return new NYStyleClamPizza();
        }
        return null;
    }
}

芝加哥披萨工厂与纽约披萨工厂类类似,此处直接贴测试结果:
这里写图片描述


抽象工厂模式
对披萨类只做了小部分改动,引入披萨原料类:

public abstract class Pizza {
    String name;
    Dough dough;
    Sauce sauce;
    List<String> toppings = new ArrayList<>();
    abstract void prepare();
    void bake() {
        System.out.println("烘焙25-30min");
    }
    void cut() {
        System.out.println("将披萨切块");
    }
    void box() {
        System.out.println("将披萨装盒");
    }
    public String getName() {
        return name;
    }
}

纽约芝士披萨:

public class NYStyleCheesePizza extends Pizza {
    PizzaIngredientFactory ingredient;
    public NYStyleCheesePizza(PizzaIngredientFactory ingredient) {
        name = "纽约风味芝士披萨";
        toppings.add("纽约风味--芝士");
        this.ingredient = ingredient;
    }
    @Override
    void prepare() {
        System.out.println("======================");
        System.out.println(name);
        dough = ingredient.creatDouge();
        sauce = ingredient.creatSauce();
        System.out.println("  调味品:");
        for (int i = 0; i < toppings.size(); i++) {
            System.out.println("         " + toppings.get(i));
        }
    }
}

接下来是披萨原料工厂类,因为酱料与面饼类似,就只写面饼的代码吧
面饼抽象类:

public abstract class Dough {
    String name;
    public String getName() {
        return name;
    }
}

纽约厚面饼:

public class NYDough extends Dough {
    public NYDough() {
        name = "    纽约面饼...";
        System.out.println(name);
    }
}

披萨原料工厂接口:

public interface PizzaIngredientFactory {
    Dough creatDouge();
    Sauce creatSauce();
}

纽约披萨原料工厂:

public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
    @Override
    public Dough creatDouge() {
        return new NYDough();
    }
    @Override
    public Sauce creatSauce() {
        return new NYSauce();
    }
}

测试结果:
这里写图片描述

以上完整代码可以在http://download.csdn.net/download/sjm01234/10200158下载( ˃ᴗ˂ )

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
工厂模式是一种常见的创建型设计模式,用于创建对象,而不是通过直接调用构造函数来创建它们。工厂模式定义了一个接口,用于创建相关对象,但是让子类决定要实例化的类。在C++中,工厂模式可以通过以下步骤实现: 1. 创建一个抽象基类,该类定义了一个纯虚拟函数,该函数将返回一个指向基类的指针。这个基类就是我们的工厂接口。 ```c++ class Product { public: virtual ~Product() {} virtual void operation() = 0; }; ``` 2. 创建具体的产品类,它们继承自抽象基类,并实现了其纯虚拟函数。这些类就是我们的具体产品。 ```c++ class ConcreteProductA : public Product { public: void operation() override { /* 具体产品 A 的操作 */ } }; class ConcreteProductB : public Product { public: void operation() override { /* 具体产品 B 的操作 */ } }; ``` 3. 创建一个工厂类,该类实现了工厂接口,并根据需要创建具体的产品。这个工厂类就是我们的具体工厂。 ```c++ class Factory { public: virtual ~Factory() {} virtual std::unique_ptr<Product> createProduct() = 0; }; class ConcreteFactoryA : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductA>(); } }; class ConcreteFactoryB : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductB>(); } }; ``` 4. 在客户端代码中使用具体工厂创建具体产品。 ```c++ int main() { std::unique_ptr<Factory> factory = std::make_unique<ConcreteFactoryA>(); std::unique_ptr<Product> product = factory->createProduct(); product->operation(); return 0; } ``` 这就是工厂模式的基本实现方式。通过这种方式,我们可以将对象的创建过程与客户端代码分离,从而更好地实现模块化和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值