【设计模式-02】工厂设计模式

工厂设计模式是一种创建型设计模式,用于通过抽象工厂类创建对象,实现客户端代码与具体实例化解耦。文章提供了一个动物工厂的示例,展示如何通过抽象工厂和具体工厂(如DogFactory和CatFactory)创建Animal接口的实现(Dog和Cat)。这种模式提高了代码的灵活性和可扩展性。
摘要由CSDN通过智能技术生成

1. 前言

在这里插入图片描述

工厂设计模式是一种创建型设计模式,它的主要目的是通过一种特定的方式来创建对象,而不需要直接实例化这些对象。
在工厂模式中存在一个抽象工厂类,该类充当组件生产的工厂,负责根据传递给它的参数动态的创建具体的对象。

在Java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则。如果我们使用工厂来生产对象,我们就只和工厂打交道就可以了,彻底和对象解耦,如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦。

工厂设计模式的核心思想是将对象的创建责任转移到工厂类上,使得客户端代码从具体类的实例化中解耦出来。这样更容易维护和扩展代码,因为客户端只需要和工厂接口交互,而不需要知道具体的实现细节。

工厂模式包括三个核心组件:

1.抽象工厂类:定义创建对象的接口,客户端只能通过它来创建具体的对象。

2.具体工厂类:实现抽象工厂类中定义的接口,根据不同的参数来创建具体的对象。

3.产品类:实现抽象工厂接口中定义的抽象方法,是具体对象的定义。

2.举个🌰

// 抽象工厂类
public abstract class AnimalFactory{
    public abstract Animal createAnimal();
}

// 具体工厂类
public class DogFactory extends AnimalFactory{
    @Override
    public Animal createAnimal(){
        return new Dog();
    }
}

public class CatFactory extends AnimalFactory{
    @Override
    public Animal createAnimal(){
        return new Cat();
    }
}

// 产品类
public interface Animal{
    void speak();
}

public class Dog implements Animal{
    @Override
    public void speak(){
        System.out.println("Woof!");
    }
}

public class Cat implements Animal{
    @Override
    public void speak(){
        System.out.println("Meow!");
    }
}

// 客户端代码
public static void main(String[] args){
    AnimalFactory dogFactory = new DogFactory();
    Animal dog = dogFactory.createAnimal();
    dog.speak();

    AnimalFactory catFactory = new CatFactory();
    Animal cat = catFactory.createAnimal();
    cat.speak();
}

在上述示例中,AnimalFactory是抽象工厂类,DogFactory和CatFactory是具体工厂类,Animal是抽象产品类,Dog和Cat是具体产品类。客户端代码只与AnimalFactory和Animal接口交互,而不关心具体的实现细节。工厂类根据传递的参数动态创建具体对象,从而使得代码更加灵活和可扩展。

3.另一个🌰

详见《重学设计模式》第1节:⼯⼚⽅法模式
相应代码:见附录
在这里插入图片描述

4. 黑马讲解工厂设计模式

黑马工厂设计模式课程地址

4.1 简单工厂

简单工厂不是一种设计模式,反而比较像是一种编程习惯。

简单工厂包含如下角色:

  1. 抽象产品 :定义了产品的规范,描述了产品的主要特性和功能。
  2. 具体产品 :实现或者继承抽象产品的子类
  3. 具体工厂 :提供了创建产品的方法,调用者通过该方法来获取产品。

举个例子,这里AmericanCoffee与LatteCoffee继承Coffee类,通过SimpleCoffeeFactory来创建出Coffee对象,如果有新的Coffee品类对象,只需要修改SimpleCoffeeFactory即可。
在这里插入图片描述

package com.itheima.pattern.factory.simple_factory;

/**
 * @version v1.0
 * @ClassName: Coffee
 * @Description: 咖啡类
 * @Author: 黑马程序员
 */
public abstract class Coffee {

    public abstract String getName();

    //加糖
    public void addsugar() {
        System.out.println("加糖");
    }

    //加奶
    public void addMilk() {
        System.out.println("加奶");
    }
}
package com.itheima.pattern.factory.simple_factory;


/**
 * @version v1.0
 * @ClassName: LatteCoffee
 * @Description: 拿铁咖啡
 * @Author: 黑马程序员
 */
public class LatteCoffee extends Coffee {

    public String getName() {
        return "拿铁咖啡";
    }
}

----------------
package com.itheima.pattern.factory.simple_factory;


/**
 * @version v1.0
 * @ClassName: AmericanCoffee
 * @Description: 没事咖啡
 * @Author: 黑马程序员
 */
public class AmericanCoffee extends Coffee {

    public String getName() {
        return "美式咖啡";
    }
}
package com.itheima.pattern.factory.simple_factory;

/**
 * @version v1.0
 * @ClassName: CoffeeStore
 * @Description: TODO(一句话描述该类的功能)
 * @Author: 黑马程序员
 */
public class CoffeeStore {

    public Coffee orderCoffee(String type) {

        SimpleCoffeeFactory factory = new SimpleCoffeeFactory();
        //调用生产咖啡的方法
        Coffee coffee = factory.createCoffee(type);

        //加配料
        coffee.addMilk();
        coffee.addsugar();

        return coffee;
    }
}
package com.itheima.pattern.factory.simple_factory;

/**
 * @version v1.0
 * @ClassName: Client
 * @Description: TODO(一句话描述该类的功能)
 * @Author: 黑马程序员
 */
public class Client {
    public static void main(String[] args) {
        //创建咖啡店类对象
        CoffeeStore store = new CoffeeStore();
        Coffee coffee = store.orderCoffee("latte");

        System.out.println(coffee.getName());
    }
}
package com.itheima.pattern.factory.simple_factory;

/**
 * @version v1.0
 * @ClassName: SimpleCoffeeFactory
 * @Description: 简单咖啡工厂类,用来生产咖啡
 * @Author: 黑马程序员
 */
public class SimpleCoffeeFactory {

    public Coffee createCoffee(String type) {
        //声明Coffee类型的变量,根据不同类型创建不同的coffee子类对象
        Coffee coffee = null;
        if("american".equals(type)) {
            coffee = new AmericanCoffee();
        } else if("latte".equals(type)) {
            coffee = new LatteCoffee();
        } else {
            throw new RuntimeException("对不起,您所点的咖啡没有");
        }

        return coffee;
    }
}

4.2 简单工厂模式的优缺点

  1. 优点:
    封装了创建对象的过程,可以通过参数直接获取对象。把对象的创建和业务逻辑层分开,这样以后就避免了修改客户代码,如果要实现新产品直接修改工厂类,而不需要在原代码中修改,这样就降低了客户代码修改的可能性,更加容易扩展。

  2. 缺点:
    增加新产品时还是需要修改工厂类的代码,违背了“开闭原则”。

4.3 工厂类

在这里插入图片描述

package com.itheima.pattern.factory.factory_method;

/**
 * @version v1.0
 * @ClassName: LatteCoffeeFactory
 * @Description: 拿铁咖啡工厂,专门用来生产拿铁咖啡
 * @Author: 黑马程序员
 */
public class LatteCoffeeFactory implements CoffeeFactory {

    public Coffee createCoffee() {
        return new LatteCoffee();
    }
}

--------------

package com.itheima.pattern.factory.factory_method;

/**
 * @version v1.0
 * @ClassName: AmericanCoffeeFactory
 * @Description: 美式咖啡工厂对象,专门用来生产美式咖啡
 * @Author: 黑马程序员
 */
public class AmericanCoffeeFactory implements CoffeeFactory {

    public Coffee createCoffee() {
        return new AmericanCoffee();
    }
}

--------------

package com.itheima.pattern.factory.factory_method;


/**
 * @version v1.0
 * @ClassName: AmericanCoffee
 * @Description: 没事咖啡
 * @Author: 黑马程序员
 */
public class AmericanCoffee extends Coffee {

    public String getName() {
        return "美式咖啡";
    }
}

--------------
/**
 * @version v1.0
 * @ClassName: Coffee
 * @Description: 咖啡类
 * @Author: 黑马程序员
 */
public abstract class Coffee {

    public abstract String getName();

    //加糖
    public void addsugar() {
        System.out.println("加糖");
    }

    //加奶
    public void addMilk() {
        System.out.println("加奶");
    }
}

--------------
package com.itheima.pattern.factory.factory_method;

/**
 * @version v1.0
 * @ClassName: CoffeeFactory
 * @Description: CoffeeFactory : 抽象工厂
 * @Author: 黑马程序员
 */
public interface CoffeeFactory {

    //创建咖啡对象的方法
    Coffee createCoffee();
}
--------------
package com.itheima.pattern.factory.factory_method;



/**
 * @version v1.0
 * @ClassName: CoffeeStore
 * @Description: TODO(一句话描述该类的功能)
 * @Author: 黑马程序员
 */
public class CoffeeStore {

    private CoffeeFactory factory;

    public void setFactory(CoffeeFactory factory) {
        this.factory = factory;
    }

    //点咖啡功能
    public Coffee orderCoffee() {
        Coffee coffee = factory.createCoffee();
        //加配料
        coffee.addMilk();
        coffee.addsugar();
        return coffee;
    }
}


--------------
/**
 * @version v1.0
 * @ClassName: Client
 * @Description: TODO(一句话描述该类的功能)
 * @Author: 黑马程序员
 */
public class Client {
    public static void main(String[] args) {
        //创建咖啡店对象
        CoffeeStore store = new CoffeeStore();
        //创建对象
        //CoffeeFactory factory = new AmericanCoffeeFactory();
        CoffeeFactory factory = new LatteCoffeeFactory();
        store.setFactory(factory);

        //点咖啡
        Coffee coffee = store.orderCoffee();

        System.out.println(coffee.getName());
    }
}

优点:
用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;
在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;

缺点:
每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。

附录

1.详解工厂设计模式
2.重学设计模式代码
3.重学设计模式电子版
4.重学设计模式代码Gitee仓库版
5.黑马设计模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

boy快快长大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值