设计模式-工厂模式(Factory Pattern)

简单工厂模式(Simple Factory Pattern)

介绍

简单工厂模式其实并不属于GoF23种经典设计模式,它是一个常用的编程习惯。能根据不同的参数返回不同类的实例。

3种角色

  • 抽象产品:定义产品的规范,描述产品的主要特性和功能。
  • 具体产品:实现or继承抽象产品的子类。
  • 具体工厂:提供创建产品的方法,通过调用这个来获得产品。

代码示例

题目一:使用简单工厂模式模拟女娲(Nvwa)造人(Person),如果传入参数M,则返回一个Man对象,如果传入参数W,则返回一个Woman对象,请实现该场景。

Person类(抽象产品):

public interface Person {
    public void create();
}

Man类(具体产品1):

public class Man implements Person{
    @Override
    public void create() {
        System.out.println("成功创造了男人...");
    }
}

Woman类(具体产品2):

public class Women implements Person{
    @Override
    public void create() {
        System.out.println("成功创建了女人...");
    }
}

Nvwa类(具体工厂):

public class Nvwa {
    public Person getPerson(String person1) throws Exception
    {
       if (person1.equalsIgnoreCase("M")){
            return new Man();
        } else if (person1.equalsIgnoreCase("W")){
            return new Women();
        } else {
            throw new Exception("对不起,暂时无法创造该人。");
        }
    }
}

测试代码:

public class Test {
    public static void main(String[] args) throws Exception {
        Person person;
        String person1 = "W";
        person = Nvwa.getPerson(person1);
        person.create();
    }
}

题目二:在上述基础上,现需要增加一个新的Robot类,如果传入参数R,则返回一个Robot对象,对代码进行修改并注意女娲的变化。

新增Robot类(具体产品3):

public class Robot implements Person{
    @Override
    public void create() {
        System.out.println("成功创造了机器人...");
    }
}

修改Nvwa类(具体工厂):

public class Nvwa {
    public Person getPerson(String person1) throws Exception
    {
        if (person1.equalsIgnoreCase("M")){
            return new Man();
        } else if (person1.equalsIgnoreCase("W")){
            return new Women();
        } else if (person1.equalsIgnoreCase("R")){
            return new Robot();
        } else {
            throw new Exception("对不起,暂时无法创造该人。");
        }
    }
}

总结

  • 应用场景:当使用者知道工厂需要的传入参数,并且对工厂如何生产出产品的逻辑并不关心。
  • 优点:降低耦合度(将使用者和生产着隔离)。
  • 缺点:每新增一个新的产品对象,就需要对工厂类的代码进行一次修改,这违反了设计模式中的“开闭原则”(题目二) 1

静态工厂模式(Static Factory Pattern)

将工厂类中的创建对象的功能定义为静态的,这个就是静态工厂模式,它也不是23种设计模式中的。

public class Nvwa {
    public static Person getPerson(String person1) throws Exception
    {
       if (person1.equalsIgnoreCase("M")){
            return new Man();
        } else if (person1.equalsIgnoreCase("W")){
            return new Women();
        } else if (person1.equalsIgnoreCase("R")){
            return new Robot();
        } else {
            throw new Exception("对不起,暂时无法创造该人。");
        }
    }
}

工厂方法模式(Factory Method Pattern)

介绍

为了解决简单工厂模式的这个缺点,引入:工厂方法模式。工厂方法模式又称为工厂模式,也叫虚拟构造器(Virtual Constructor),工厂方法模式主要是对“工厂”的封装,提供一个创建者的接口,将产品实例化的步骤延迟到工厂的子类完成,让工厂的子类决定需要创建什么产品。遵循了"开闭原则"。

4种角色

  • 抽象工厂:只提供创建产品的方法。
  • 具体工厂:实现抽象工厂的方法,创建具体产品。
  • 抽象产品:定义产品的规范。
  • 具体产品:实现或继承抽象产品,由具体工厂进行生产,与具体工厂一一对应

代码示例(沿用上述问题)

问题一:


/**
* 抽象工厂
**/
public interface NvwaFactory {
    Person getPerson();
}

/**
* 具体工厂
* 
* 抽象产品为Person,具体产品为Man和Women
* 这种工厂模式可以通过不同的具体工厂创建出不同的具体产品
**/
public class ManFactory implements NvwaFactory{
    @Override
    public Person getPerson() {
        return new Man();
    }
}

public class WomenFactory implements NvwaFactory{
   @Override
    public Person getPerson() {
        return new Women();
    }
}

测试代码:

public class Test{
    public static void main(String[] args) {  
        new ManFactory().getPerson().create();
        new WomenFactory().getPerson().create();
    }  
} 

问题二:
只需要新增Robot类和RobotFactory就可以了。

通过上述例子,我们需要创建哪个产品,不再是靠外界传入参数决定,而是取决于抽象工厂使用的是具体哪个实现类。这种基于多态性设计的模式,使得产品的实例化延迟到具体子类之中,通过替换不同的实现子类就能达到新增和切换产品的目的。

总结

  • 优点:在获取对象时只需要知道具体工厂的名称就可以得到对应的对象,无须知道具体创建过程;在系统增加新的类时只需要添加对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则;
  • 缺点:每增加一个类就要增加一个对应的具体工厂类,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。

抽象工厂模式(Abstract Factory Pattern)

介绍

4种角色

  • 抽象工厂:
  • 具体工厂:
  • 抽象产品:
  • 具体产品:

代码示例

总结

  • 优点:
  • 缺点:

  1. 开闭原则:即“开放-闭合原则”,软件架构应该设计成对于修改来说,代码实体是关闭的,而对于扩展来说,代码实体则是开放的。通俗一点讲,开闭原则是鼓励通过“新增”来代替“变化”。鼓励设计者将业务逻辑抽象化,将逻辑的本质设计成抽象类或者接口,逻辑的具体实践操作设计成具体实现类。 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值