你真的懂工厂模式吗?

抽象工厂模式和工厂模式的区别? - 贾不假的回答 - 知乎 https://www.zhihu.com/question/20367734/answer/1089721250

简单工厂模式

引入

比如设计一个场景:博客系统的文章想要分为两类,一类是生活文章,一类是工作文章。

使用简单工厂模式去实现这个场景:

1. 两个文章类共同的父接口:ContentCenter (产品)

2. 两个文章类具体实现 (具体产品)

3. 文章工厂,通过传入的type,返回对应的文章实列。(工厂)

以上就凑齐了简单工厂的三个要素 产品、具体产品、工厂。

// 产品
public interface ContentCenter {
    String getContent(int aid);
}

// 具体产品
public class DayPartImp implements ContentCenter {
    @Override
    public String getContent(int aid) {
        String str = "生活文章:我爱妹妹";
        return str;
    }
}

public class WorkPartImp implements ContentCenter{

    @Override
    public String getContent(int aid) {
        String str = "work文章:划水一天天";
        return str;
    }
}


// 工厂
public class ContentFactroy {
    public ContentCenter getContentPart(int type,int aid) throws Exception{
        if(type == 1){
            return new WorkPartImp();
        }else{
            return new DayPartImp();
        }
    }
}

简单工厂模式适用于复杂对象的创建,用户只需要通过工厂得到对象,加以使用就行了,不用去管对象是怎么创建的。

问题

如果现在需要新加一类文章,那么就需要去修改工厂中的ifelse了,违反了开闭原则。

工厂方法模式

接着上面的例子,如果使用工厂方法来实现,那应该是这样的:

四部分: 工厂、具体工厂、产品、具体产品

// 产品
public interface ContentCenter {
    String getContent(int aid);
}

// 具体产品
public class DayPartImp implements ContentCenter {
    @Override
    public String getContent(int aid) {
        String str = "生活文章:我爱妹妹";
        return str;
    }
}

public class WorkPartImp implements ContentCenter{

    @Override
    public String getContent(int aid) {
        String str = "work文章:划水一天天";
        return str;
    }
}

// 工厂
public interface ContentFactoryBig {
    ContentCenter createContent();
}

// 具体工厂
class WorkFactory implements ContentFactoryBig{
    @Override
    public ContentCenter createContent() {
        return new WorkPartImp();
    }
}


class DayFactroy implements ContentFactoryBig{
    @Override
    public ContentCenter createContent() {
        return new DayPartImp();
    }
}

也就是说,每一种产品对象的创建,都对应这一个具体的工厂去创建,缺点是类会创建得比较多,优点是符合开闭原则,要是有新加的产品,只需要新加一个具体工厂就行。于简单工厂同样的,屏蔽了对象的创建过程。

抽象工厂模式

上面的工厂方法虽然看起来挺牛逼,但是其核心:每个工厂只能创建一种产品。 那么如果产品比较多,就会出现很多很多工厂类的情况。

为了避免这个问题呢,抽象工厂模式就出来啦!它把有关联的一类产品看成一个“产品族”,使用同一个工厂来创建。

比如咱引入一个列子:

KFC有现在需要同时卖鸡腿和可乐,但是不管是鸡腿和可乐都会有两个步骤,1.生产 2.卖(也可以看做是生产两种产品哦),那么咱需要准备的有:

1、 KFCFactory  KFC工厂接口  (抽象工厂)

2、可乐工厂和鸡腿工厂  (具体工厂)

3、生产步骤,卖的步骤 (抽象产品)

4、 生产可乐、卖出可乐。 生产鸡腿、卖出鸡腿。 (具体产品)

// 抽象工厂
public interface KFCFactory {
    PrepareThing createPrepareThingForSale();
    SaleThing createSale();
}

// 具体工厂
public class JituiFactory implements KFCFactory {
    @Override
    public PrepareThing createPrepareThingForSale() {
        return new JituiPrepareThing();
    }

    @Override
    public SaleThing createSale() {
        return new JituiSale();
    }
}

public class CeleFactory implements KFCFactory {
    @Override
    public PrepareThing createPrepareThingForSale() {
        return new KelePrepareThing();
    }

    @Override
    public SaleThing createSale() {
        return new keleSale();
    }
}

// 抽象产品
public interface SaleThing {
    void saySaleWhich();
}

public interface PrepareThing {
    void sayPrepare();
}

// 具体产品
public class JituiSale implements SaleThing {
    @Override
    public void saySaleWhich() {
        System.out.println("卖鸡腿拉");
    }
}

public class keleSale implements SaleThing {
    @Override
    public void saySaleWhich() {
        System.out.println("卖可乐,卖可乐");
    }
}

public class KelePrepareThing implements PrepareThing {
    @Override
    public void sayPrepare() {
        System.out.println("准备可乐呜呼呼");
    }
}

public class JituiPrepareThing implements PrepareThing {
    @Override
    public void sayPrepare() {
        System.out.println("鸡腿正在准备拉");
    }
}

(对不起。。。例子举得不好,全想着KFC去了,还是网上那个WINDOWS和MAC 鼠标键盘的例子好理解)

产品族之间需要有逻辑或者约束,毕竟是要一起用的。

在抽象工厂模式中,增加新的产品族很方便,但是增加新的产品等级结构很麻烦。也就是说对产品族不会改变的系统,是符合开闭原则的。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值