工厂设计模式(Factory)

工厂设计模式(Factory)

首先要明确,工厂模式分为三种:

  1. 简单工厂设计模式
  2. 工厂方法
  3. 抽象方法

一:简单工厂模式

首先来简单了解一下简单工厂模式是什么吧~

介绍:
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

好了好了,牛皮牛皮 说实话看概念我是真的一点都没看懂,什么垃圾解释,下面让我用人话重新剖析一下这句话在说什么吧~

首先我想举个例子:
好,现在我们来到了一片果园,这里漫山遍野都是果树,里面有葡萄,苹果等等等等。这里提一嘴,为什么我们需要工厂模式,首先,我们不能说想用一个小黄车,我们当场去创建这个小黄车,零件什么的都由我们自己去创造,我们需要的是一个工厂帮我们代工,我们想用的时候推出来一辆就可以了,工厂模式就是可以帮我们隐藏具体的建造细节。好了差不多就这样,我们将话题再转向这片果园~

好的,有些同学要说了:“我知道!你要抽象出来一个水果类”。

哎呀真聪明,都学会抢答了,是的,我们这里抽象一个水果类出来:

public abstract class Fruit {
    abstract void grow();
    abstract void harvest();
    abstract void plant();
}

我觉得大家都是成年人了,不会的单词百度一下也应该知道什么意思了,这里还是帮你们标注一下吧(harvest:收获)

这里的知识很简单,用一个抽象类,把水果共有的特征抽象出来,有些同学觉得抽象的东西太抽象了,不好理解,这里的抽象,你可以理解成 抽出像的部分。比方说这里的成长,种植,收获,都是水果必经之路。

好,我们可以创建一个苹果类和葡萄类来继承这个抽象类,重写这些方法,让水果更加丰满

public class Apple extends Fruit{
    @Override
    void grow() {
        System.out.println("苹果成长");
    }

    @Override
    void harvest() {
        System.out.println("苹果收获");
    }

    @Override
    void plant() {
        System.out.println("苹果种植");
    }
}

然后这里是葡萄类:

public class Grape extends Fruit{
    @Override
    void grow() {
        System.out.println("葡萄成长");
    }

    @Override
    void harvest() {
        System.out.println("葡萄收获");
    }

    @Override
    void plant() {
        System.out.println("葡萄种植");
    }
}

好的,有些同学就要问了,工厂在哪里,别急,看下面的代码:

public class FruitFactory {

    public static Fruit factory(String fruitName){
        if ("apple".equals(fruitName)){
            System.out.println("包装苹果");
            return new Apple();
        }else if ("grape".equals(fruitName)){
            System.out.println("包装葡萄");
            return new Grape();
        }else {
            return null;
        }
    }
}

这里我得解释一下这段代码:这是一个静态的工厂,传进来一个水果名,我们这里做一下判断,如果是苹果,我们让他包装苹果,并且返回一个新的苹果实例。葡萄也是一样的方法,直接 else if 判断一下就行(极大的加强了程序的拓展能力)。这里我们可以看到,我们丰富了建造过程,给他包装了一下。
接下来让我们看看客户端怎么操作(也就是主函数)

public class Client {
    public static void main(String[] args) {
        try {
            Fruit grape = FruitFactory.factory("grape");
            grape.plant();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

这里我们明显的看到:我现在要一个水果,但是我们没有new这个水果,而是把工厂拿过来,直接调用方法,传参数。

好了,讲完了,是不是很简单,但是我们可以设想一下:

是不是在某些系统中,有控制台会询问你执行什么操作的话,反反复复总是那几句,所以你有没有想过,这些话不是写死在程序里面的,这个菜单可能是在外边一个文件里面,用的时候加载进来,当你需要用的时候,就像引用常量一样,把它映射过去,这样将来调用欢迎语句的时候,欢迎语句可能会改变,但是引用没有改变。这里我们就可以使用简单工厂模式的思想来考虑。

下面我把这个简单工厂模式的UML图放在下边了:
简单工厂实例UML图


二:工厂方法

接下来要讲的工厂方法其实就是一个升级,接下来我还是举一个例子来理解工厂方法,以及为什么要使用工厂方法。
工厂方法UML图
这里我们先看一张UML图,请认真看图,这里是关键,这个例子是有关苹果公司生产的产品的,众所周知,苹果公司比较出名的有iPad以及iPhone(当然还有其他的我就不举例了),我们也知道,虽然这两个产品感觉差不多,但是实际上是两个不同的产品,不管是屏幕,大小,功能都不太一样,然后你让我用同一个工厂去代工又有点别扭,所以这里我把工厂类也抽象了,就是说,你要iPad,我就给你调用iPadFactory(iPad工厂),你用iPhone,我就给你调用iPhoneFactory(iPhone工厂)。懂了吗,等于就是更具体了,更详细了。接下来我们看一下代码你就更了解了。

首当其冲的当然是创新的地方,也就是抽象的工厂类(我这里定义的是接口,一个意思),这里工厂就比较简单了,主要功能就是生产产品。

public interface Factory {
    public Product factory();
}

然后就是两个加工厂了,实现Factory接口,重写生产方法(大体都差不多是相似的):

public class IpadFactory implements Factory{
    @Override
    public Product factory() {
        return new Ipad();
    }
}
public class IphoneFactory implements Factory{
    @Override
    public Product factory() {
        return new Iphone();
    }
}

还有更简单的,我定义了一个产品接口:

public interface Product {
}

是不是很简单,里面啥也没有hhh,但是这样可以提高你的一个代码复用以及拓展的能力。
接下来就是我们的两个产品了,一个是iPad,另一个是iPhone:

public class Ipad implements Product{

    public Ipad(){
        System.out.println("Ipad");
    }

}
public class Iphone implements Product{

    public Iphone(){
        System.out.println("Iphone");
    }

}

好了,产品定义好了,工厂也定义好了,是不是该看看主函数什么样了~
主函数:

public class Client {

    public static void main(String[] args) {
        Factory c1,c2;
        Product p1,p2;

        c1 = new IpadFactory();
        p1 = c1.factory();

        c2 = new IphoneFactory();
        p2 = c2.factory();
    }

}

这我都不用解释什么吧,都很简单,c1,c2两个产品,p1,p2两个工厂,最后各用各的工厂,代码就很明了清晰。工厂方法我就先简单介绍到这里。


三:抽象工厂

有些同学又要问了,这又是什么**玩意(自动消音),别急,听完我的介绍你会豁然开朗。

这里我还是举一个例子供大家理解,这里给大家也不说苹果了,说说男人的梦想——奔驰汽车吧,众所周知,汽车也分好多品种,比方说等级不同:A系奔驰、B系奔驰。还有产地不同:中国奔驰、德国奔驰。这里产地不同,其实可以理解成完全两个产品,比方说,中国奔驰A系,和德国奔驰A系就不一样,比方说气囊数量以及位置啊,车体钢铁硬度啊什么的都不一样(总感觉越解释越麻烦) 反正你们就当是两个商品就好了。

重点在这里,我的根本意思就是说,这里情况更加复杂了,不仅工厂抽象了,这里产品也得抽象一下,你们继续看我的代码就能理解了:

首先给大家看一下这个例子的类有哪些:
类
这里可以清晰的看见:

  1. 有抽象的奔驰A和B轿车(BenzA 和 BenzB)
  2. 有中国奔A和中国奔B(BenzACN 和 BenzBCN)
  3. 有德国奔A和德国奔B(BenzAGermany 和 BenzBGermany)
  4. 有奔驰工厂(MercedesFactory)
  5. 有中国奔驰工厂(MercedesFactoryCN)
  6. 有德国奔驰工厂(MercedesFactoryGermany)
  7. 还有主函数(Client)

接下来就是详细代码,其实你只要理解了我什么意思就行,我的意思就是想说,这里的产品也是抽象出来的,工厂方法比简单工厂模式更抽象,抽象工厂又比工厂方法抽象,一级比一级抽象,一级比一级更高级,代码灵活度越来越高,拓展能力越来越强,代码能复用的可能性越大。

接下来就是代码,我们先看抽象的车辆制造工厂这里:

public interface MercedesFactory {

    public BenzA creatBenzA();
    public BenzB creatBenzB();

}

然后是详细的中国工厂和德国工厂:

public class MercedesFactoryCN implements MercedesFactory{
    @Override
    public BenzA creatBenzA() {
        System.out.println("中国生产一辆奔驰A级轿车");
        return new BenzACN();
    }

    @Override
    public BenzB creatBenzB() {
        System.out.println("中国生产一辆奔驰B级轿车");
        return new BenzBCN();
    }
}
public class MercedesFactoryGermany implements MercedesFactory{
    @Override
    public BenzA creatBenzA() {
        System.out.println("德国生产一辆奔驰A级轿车");
        return new BenzAGermany();
    }

    @Override
    public BenzB creatBenzB() {
        System.out.println("德国生产一辆奔驰B级轿车");
        return new BenzBGermany();
    }
}

工厂就分这三种,让我们看看产品类:

public abstract class BenzA {
}
public abstract class BenzB {
}

两种车我就简单表示一下,大家也可以加个构造方法让车辆更加丰满。
然后看看继承产品类的中国的两款车吧:

public class BenzACN extends BenzA{
    public BenzACN(){
        System.out.println("中国的奔驰A");
    }
}
public class BenzBCN extends BenzB{
    public BenzBCN(){
        System.out.println("中国的奔驰B");
    }
}

然后再看看德国的两款车:

public class BenzAGermany extends BenzA{
    public BenzAGermany(){
        System.out.println("德国的奔驰A");
    }
}
public class BenzBGermany extends BenzB{
    public BenzBGermany(){
        System.out.println("德国的奔驰B");
    }

}

就是这么简单,我们可以通过这种方法,让代码更加整洁,所以就剩下主函数没有看了:

public class Client {
    public static void main(String[] args) {
        MercedesFactory factory_germany = new MercedesFactoryGermany();
        BenzA a2 = factory_germany.creatBenzA();
    }
}

这里主函数只要new一个工厂就可以生产轿车啦!完美!是不是很简洁!这里工厂模式就讲完啦,感觉怎么样,懂了吗我的宝贝嘻嘻嘻

好了,其实设计模式是一种思维,不是说强迫你使用这些设计模式,而是能用到就用,用不到也不所谓,只是当你有一天觉得自己的代码臃肿不堪的时候,你可以试试设计模式,会让你的代码水平提升到一个新的水平。


  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值