常用设计模式 - 工厂模式

工厂模式是创建型模式中一种比较常用的设计模式。他用工厂方法代替用户进行new操作,大大减少了new操作产生的时间消耗。工厂模式在很多框架或是网站中大量运用,是一种不得不掌握的设计模式。

小洪的故事

今日出演:小洪、强哥

话说今天放学的档口,强哥又拍了拍小洪的肩膀。转头看见强哥,小洪不禁倒吸了一口凉气。

“强哥别找我去吃烤肉了,上次我吃完那顿回到宿舍上吐下泻的,顶不住啊!”

“老弟啊,这次我们不去吃烤肉了,上次我被女朋友教训得那叫一个惨!今天我们下馆子吃几个菜吧!”强哥说道。

“外面有一家中华茶楼不错,今天好像有活动打折呢!”小洪再一次动心了。

“那就走嘞!”

简单工厂

“你知道吗,像茶楼、菜馆这些,都是遵循着工厂模式进行营业的哦。”在公交上,强哥又开启了他的学霸模式。

“哦?那是怎么样的呢?”

public class Restruant {
    public static Food makeFood(String food){
        if(food.equals("拉面")){
            Food food1 = new Noodle();
            return food1;
        }else if(food.equals("饺子")){
            Food food1 = new Dumping();
            return food1;
        }else{
            return null;
        }
    }
}

上面就是一个餐馆类,客户端只需要将想要的食物传进去,就可以不通过 new 关键字来创建对象了,客户端想要调用就通过以下的方式进行调用。

public class People {
    public static void main(String[] args) {
        Restruant.makeFood("饺子").name();
        Restruant.makeFood("拉面").name();
    }
}

“这样你在想要吃饺子的时候,就不需要进行 new,也不需要关注饺子实现的细节。“

“哇,也太下饭了这知识,我待会就决定吃饺子了!”

“你关注点倒是离谱得很。”

工厂方法

小洪和强哥终于抵达了中华茶楼,他俩找了个靠窗的位置坐下来。

“今天我要学以致用,且看我如何用简单工厂点一份新鲜的饺子!”小洪看到菜单,看似所向披靡。

“哎!老弟啊,你不会举一反三啊,你想想,如果你现在想吃牛肉水饺怎么办?”

“啊?那就在工厂中加入牛肉水饺啊。就像这样”

public class Restruant {
    public static Food makeFood(String food){
        if(food.equals("拉面")){
            Food food1 = new Noodle();
            return food1;
        }else if(food.equals("饺子")){
            Food food1 = new Dumping();
            return food1;
        }else if(food.equals("牛肉水饺")){
            Food food1 = new BeefDumping();
            return food1;
        }else{
            return null;
        }
    }
}

“那如果我想吃羊肉水饺呢?也要往里面继续加,如果以后我需要更多的需求呢,你会发现这个工厂类将变得很大,而且难以维护,用软件工程导论里的话,叫做耦合度太高了。”

“那怎么办?”

“其实像中华茶楼这么大的招牌,肯定不止一个厨房,他们的厨房是有分工的,一个厨房做饺子,一个厨房做拉面,将一个工厂变成两个或多个工厂。这样他们的管理和维护将会更简单。简单工厂的解决方法也是这样的。”

“我知道了,像下面这样表示。”

public interface Restruant {
    Food makeFood(String name);
}

public class DumpingFactory implements Restruant {
    @Override
    public Food makeFood(String food){
        if(food.equals("牛肉饺子")){
            Food food1 = new BeefDumping();
            return food1;
        }else if(food.equals("鸡肉饺子")){
            Food food1 = new ChickenDumping();
            return food1;
        }else{
            return null;
        }
    }
}

public class NoodleFactory implements Restruant {
    @Override
    public Food makeFood(String food){
        if(food.equals("牛肉拉面")){
            Food food1 = new BeefNoodle();
            return food1;
        }else if(food.equals("鸡肉拉面")){
            Food food1 = new ChickenNoodle();
            return food1;
        }else{
            return null;
        }
    }
}

“是的,这就是工厂方法,在需要多个类别或是多个工厂的时候进行使用。”强哥点点头,看来小洪还是有举一反三的能力的。

抽象工厂

酒足饭饱,茶足饭饱之后,小洪和强哥走出茶楼,准备在街上散散步。

“强哥,你看那边,还有一家 [中华酒楼] 。”小洪指着远处。

“哦豁,这又涉及抽象工厂模式了。”强哥又开始了。

“抽象工厂是啥?“

“抽象工厂里有一个产品族的概念,就比如:中华茶楼里的拉面和饺子是同一个产品族,而中华酒楼的拉面和饺子属于一个产品族。”

“理解,但是这跟抽象工厂有什么关系吗?”

“来看一下我画的类图就知道了。”

在这里插入图片描述

现在我们已经不定义什么饺子工厂、拉面工厂这些产品工厂了。我们直接将整个餐馆定义为工厂,每个工厂负责整个产品族的生产。而他们都实现了餐馆的接口,但是餐馆这个总接口是干嘛的我们也不需要管。

public interface Restruant {
    Dumping makeDumping();
    Noodle makeNoodle();
}

public class ChaLou implements Restruant {
    @Override
    public Dumping makeDumping() {
        return new ChaLouDumping();
    }

    @Override
    public Noodle makeNoodle() {
        return new ChaLouNoodle();
    }
}

public class JiuLou implements Restruant {
    @Override
    public Dumping makeDumping() {
        return new JiuLouDumping();
    }

    @Override
    public Noodle makeNoodle() {
        return new JiuLouNoodle();
    }
}

客户端想要调用的话,需要新建一个自己想要的工厂,然后用这个工厂去实现你想要吃的各种食物。如下所示:

public class People {
    public static void main(String[] args) {
        Restruant chalou = new ChaLou();

        chalou.makeDumping().name();
        chalou.makeNoodle().name();
    }
}

运行结果为:

中华茶楼的饺子
中华茶楼的拉面

“但这样,每次新增一种食物不就会很难?比如中华茶楼想新增汤圆这种食物,就实现汤圆接口、还要在总接口 Restruant 上新增汤圆的方法,最后再在自己的工厂类中实现自己的方法。”

“对,这就是抽象工厂模式的弊端,如果想要加一种产品,就需要修改所有工厂,在扩展上极为不便。”

“这样啊,那老哥这顿饭怎么还是你请啊?”小洪的注意力还是不能坚持三秒。

“没事,这家好吃,而且也不贵,明天就带女朋友来这里吃了。”

“可是明天就没有打折了呀!”

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值