Fun论设计模式之1:简单工厂模式(Factory Pattern)

转自仓大神博文  https://www.cnblogs.com/xrq730/p/6405557.html,在此基础之上加入了自己的理解

简单工厂模式

简单工厂模式是类的创建模式,又叫做静态工厂方法模式。简单工厂模式由一个工厂对象决定生产出哪一种产品类的实例。

为什么要使用简单工厂模式

原因很简单:解耦。

A对象如果要调用B对象,最简单的做法就是直接new一个B出来。这么做有一个问题,假如C类和B类实现了同一个接口/继承自同一个类,系统需要把B类修改成C类,程序不得不重写A类代码。如果程序中有100个地方new了B对象,那么就要修改100处。

这就是典型的代码耦合度太高导致的"牵一发动全身"。所以,有一个办法就是写一个工厂IFactory,A与IFactory耦合,修改一下,让所有的类都实现C接口并且IFactory生产出C的实例就可以了。

下面举个栗子

  以前顾客要拿水果,是要自己到果树那里拿的。

  水果类是这样的:

public interface Fruit
{
    void grow();// 生长
    void harveset(); // 收货
    void plant();// 种植
}
Frult

  水果有俩子类,叫做苹果和橙子:

public class Apple implements Fruit
{
    public void grow()
    {
        System.out.println("Apple.grow()");
    }

    public void harveset()
    {
        System.out.println("Apple.harveset()");
    }

    public void plant()
    {
        System.out.println("Apple.plant()");
    }
}
Apple
public class Orange implements Fruit
{
    public void grow()
    {
        System.out.println("Orange.grow()");
    }

    public void harveset()
    {
        System.out.println("Orange.harveset()");
    }

    public void plant()
    {
        System.out.println("Orange.plant()");
    }
}
Orange

  人们需要到果树下种植和采摘:

public static void main(String[] args)
{
    Fruit fruit0 = new Apple();
    fruit0.grow();
    Fruit fruit1 = new Orange();
    fruit1.harveset();
    Fruit fruit2 = new Apple();
    fruit2.grow();
}
GetAppleOrange

  后来人们吃腻了,要换成西瓜和葡萄:

public class Grape implements Fruit
{
    public void grow()
    {
        System.out.println("Grape.grow()");
    }

    public void harveset()
    {
        System.out.println("Grape.harveset()");
    }

    public void plant()
    {
        System.out.println("Grape.plant()");
    }
    
    public void pick()
    {
        System.out.println("Grape.pick()");
    }
}
Grape
public class Watermelon implements Fruit
{
    public void grow()
    {
        System.out.println("Watermelon.grow()");
    }

    public void harveset()
    {
        System.out.println("Watermelon.harveset()");
    }

    public void plant()
    {
        System.out.println("Watermelon.plant()");
    }
    
    public void cut()
    {
        System.out.println("Watermelon.cut()");
    }
}
Watermalon

  人们吃之前还要做切和采摘这些动作(默认橙子和苹果收获之后直接吃):

public static void main(String[] args)
{
    Fruit fruit0 = new Watermalon();
    fruit0.cut();
    fruit0.grow();
    Fruit fruit1 = new Grape();
    fruit1.pick();
    fruit1.harveset();
}
GetWatermalonGrape

  如果中间有人(工厂)能把成品处理出来就好了。。。

  于是果树下出现了园丁:

public class Gardener
{
    public static Fruit getFruit(String fruit)
    {
        if ("watermalon".equalsIgnoreCase(fruit))
        {
            Fruit fruit = new Watermalon();
            fruit.cut();
            return fruit;
        }
        else if ("grape".equalsIgnoreCase(fruit))
        {
            Fruit fruit = new Grape();
            fruit.pick();
            return fruit;
        }
        else
        {
            return null;
        }
    }
}
Gardener

  人们直接从园丁那里取水果(这里的园丁就是工厂):

public static void main(String[] args)
{
    Fruit fruit0 = Gardener.getFruit("watermalon");
    fruit0.harveset();
    Fruit fruit1 = Gardener.getFruit("GRAPE");
    fruit1.harveset();
}
GetByGardener

  如果园丁需要不同类型的没见过的水果呢?

  反射一下水果类就解决了

public class Gardener
{
    public static Fruit getFruit(String fruitPath) throws Exception
    {
        Class<?> c = Class.forName(fruitPath);
        return (Fruit)c.newInstance();       
    }
}
View Code

  

工厂模式的优缺点

优点:

1、简单优化了软件体系结构,明确了各自功能模块的职责和权利

2、通过工厂类,外界不需要直接创建具体产品对象,只需要负责消费,不需要关心内部如何创建对象

缺点:

1、改进前的简单工厂模式全部创建逻辑都集中在一个工厂类中,能创建的类只能是考虑到的,如果需要添加新的类,就必须改变工厂类了

2、改进前的简单工厂模式随着具体产品的不断增多,可能会出现共产类根据不同条件创建不同实例的需求,这种对条件的判断和对具体产品类型的判断交错在一起,很难避免功能模块的蔓延,对系统的维护和扩展不利

3、改进后的简单工厂模式主要是使用反射效率会低一些

原文地址:https://www.cnblogs.com/dgutfly/p/10449984.html