前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式之工厂模式

设计模式之工厂模式

作者头像
用户8902830
发布2021-08-12 11:00:45
2660
发布2021-08-12 11:00:45
举报
文章被收录于专栏:CodeNone

估计这个系列的文章是每篇一个设计模式,重点是为了让大家能够利用休闲时间,比如说5分钟就能够比较全面通俗易懂地了解设计模式。

前言

接下来就是手撕设计模式的环节了,设计模式本身并不难,难的是在实际情况下是否能自然地想到使用设计模式。简单来说设计模式的本质是一种思想,一种重构代码,使代码高可用的思想。

在面向对象设计(写代码)的时候一般会遵循以下几个原则,当然初学肯定很难遵循,但是至少得了解是什么,然后有意识地往这个方向靠。

  • 单一职责原则: 一个类只负责具体的某一个功能,当新需求出现的时候,最好的做法是增加一个类而不是修改原来的类。
  • 开闭原则: 当开发好一个类后,这个类需要有良好的扩展性,可以通过继承和多态来添加新功能。
  • 里氏替换原则: 把父类换成子类,程序不会报错,但是反过来就不行。通俗地来讲,子类能够扩展父类的功能,但是不能改变原来父类原有的功能。
  • 接口隔离原则: 客户端不应该依赖于它所不需要的接口,设计接口时尽量精简单一。
  • 依赖倒置原则: 高级模块不应该依赖低级模块,两者都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象。

这些理论的东西我已经尽可能简单地讲了

简单点

工厂及抽象工厂模式


有关工厂模式有三种,简单工厂,工厂,抽象工厂,通常来说,前面两者并为一项说工厂模式。

那么什么叫工厂模式呢,最简单来说,你没必要和产品打交道,你直接和工厂打交道,把new 产品的操作交给工厂来做。

1、简单工厂模式


之所以简单,是因为它只涉及到具体工厂类,抽象产品类和具体产品类,下面直接来看代码。

抽象产品类:

手机

代码语言:javascript
复制
public abstract class AbstractPhone {
    public abstract void use();
}

具体产品类:

魅族手机和一加手机

代码语言:javascript
复制
public class Meizu extends AbstractPhone{
    @Override
    public void use() {
        System.out.println("正在使用魅族手机");
    }
}
代码语言:javascript
复制
public class OnePlus extends AbstractPhone {
    @Override
    public void use() {
        System.out.println("正在使用一加手机");
    }
}

具体工厂类:

生产手机的工厂

代码语言:javascript
复制
public class PhoneFactory {
    public AbstractPhone createPhone(String brand) {
        if(brand.equals("一加")) {
            return new OnePlus();
        } else if(brand.equals("魅族")) {
            return new Meizu();
        } else {
            System.out.println("没有该品牌的生产权");
            return null;
        }
    }
}

测试类:

代码语言:javascript
复制
@Test
public void test01() {
    //新建一个工厂
    PhoneFactory factory = new PhoneFactory();   
    
    //我们不必要跟产品打交道,告诉工厂需要一部一加手机即可
    AbstractPhone onePlus = factory.createPhone("一加"); 
    onePlus.use();

    AbstractPhone meiZu = factory.createPhone("魅族");
    meiZu.use();
}

以上就是简单工厂的实现方式,总结就是

  1. 有个抽象产品类或者接口
  2. 具体产品继承或者实现抽象产品
  3. 具体工厂类,根据需求生产产品

UML类图:

普通工厂UML

2、工厂模式


现在问题来了,如果这个工厂继续和小米,华为合作的话

需要加钱

开玩笑开玩笑,除了具体产品类需要增加,是不是也需要修改具体工厂类,这是我们不希望看到的。设计好的类,最好就是不要是在增加需求的时候改变类。

所以想到了把生产工厂抽象化,需要增加小米,只需要添加一个小米的生产类,而不改动已有的工厂类。这样就是工厂模式。

需要抽象产品类,具体产品类,抽象工厂类,具体工厂类

抽象产品类:

和上面用的是一样的抽象产品,这里不再赘述

具体产品:

同样是魅族和一加手机

抽象工厂类:

代码语言:javascript
复制
public abstract class AbstractPhoneFactory {
    public abstract AbstractPhone createPhone();
}

具体工厂类:

这个例子中有两个具体工厂类,生产魅族手机的工厂和一加手机的工厂

代码语言:javascript
复制
public class OnePlusFactory extends AbstractPhoneFactory {
    @Override
    public OnePlus createPhone() {
        return new OnePlus();
    }
}
代码语言:javascript
复制
public class MeizuFactory extends AbstractPhoneFactory {
    @Override
    public Meizu createPhone() {
        return new Meizu();
    }
}

测试类:

代码语言:javascript
复制
@Test
public void test02() {
    OnePlusFactory onePlusFactory = new OnePlusFactory();
    onePlusFactory.createPhone().use();

    MeizuFactory meizuFactory = new MeizuFactory();
    meizuFactory.createPhone().use();

}

就算之后需要增加一个小米手机类,只需要添加具体产品类,具体工厂类,并不需要修改已有的类。

类图:

3、抽象工厂模式


如果现在需求继续增加,但是不是增加品牌种类,而是。魅族和一加希望更准确地找到市场定位,所以都推出了中端手机和高端旗舰手机来冲击市场,这时候我们应该怎样设计呢。

这时候抽象工厂类不是单纯地生产手机,而是需要生产一个产品族

产品族是以产品平台为基础,通过添加不同的个性模块,以满足不同客户个性化需求的一组相关产品。

中端手机和旗舰手机就是一个产品族。

总的来说,通俗地来讲就是魅族工厂需要生产魅族的中端手机和魅族的高端手机,一加工厂需要生产一加的中端手机和高端手机。

需要抽象工厂类,具体的抽象工厂类,抽象产品类,产品族具体的抽象产品类,具体产品类

抽象产品类:

代码语言:javascript
复制
public abstract class AbstractPhone {
    public abstract void use();
}

产品族具体的抽象产品类:

中端手机和旗舰手机

代码语言:javascript
复制
public abstract class AbstractMiddlePhone extends AbstractPhone {
    @Override
    public abstract void use();
}
代码语言:javascript
复制
public abstract class AbstractTopPhone extends AbstractPhone{
    public abstract void use();
}

具体产品类:

魅族的中端手机,旗舰手机;一加的中端手机,旗舰手机。

代码语言:javascript
复制
public class MeizuMiddlePhone extends AbstractMiddlePhone {
    @Override
    public void use() {
        System.out.println("魅族中端产品");
    }
}
代码语言:javascript
复制
public class MeizuTopPhone extends AbstractTopPhone {
    @Override
    public void use() {
        System.out.println("魅族高端旗舰");
    }
}
代码语言:javascript
复制
public  class OnePlusMiddlePhone extends AbstractMiddlePhone {
    @Override
    public void use() {
        System.out.println("一加中端产品");
    }
}
代码语言:javascript
复制
public class OnePlusTopPhone extends AbstractTopPhone {
    @Override
    public void use() {
        System.out.println("一加高端旗舰");
    }
}

抽象工厂类:

代码语言:javascript
复制
public abstract class AbstractFactory {
    public abstract AbstractPhone createMiddlePhone();

    public abstract AbstractPhone createTopPhone();
}

具体抽象工厂类:

魅族生产工厂,一加生产工厂

代码语言:javascript
复制
public class MeizuFactory extends AbstractFactory {
    @Override
    public MeizuMiddlePhone createMiddlePhone() {
        return new MeizuMiddlePhone();
    }

    @Override
    public MeizuTopPhone createTopPhone() {
        return new MeizuTopPhone();
    }
}
代码语言:javascript
复制
public class OnePlusFactory extends AbstractFactory {
    @Override
    public OnePlusMiddlePhone createMiddlePhone() {
        return new OnePlusMiddlePhone();
    }

    @Override
    public OnePlusTopPhone createTopPhone() {
        return new OnePlusTopPhone();
    }
}

测试类:

代码语言:javascript
复制
@Test
public void test03() {
    OnePlusFactory onePlusFactory = new OnePlusFactory();
    MeizuFactory meizuFactory = new MeizuFactory();
    onePlusFactory.createMiddlePhone().use();
    onePlusFactory.createTopPhone().use();

    meizuFactory.createMiddlePhone().use();
    meizuFactory.createTopPhone().use();

}

类图:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CodeNone 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 工厂及抽象工厂模式
  • 1、简单工厂模式
    • 抽象产品类:
      • 具体产品类:
        • 具体工厂类:
          • 测试类:
            • UML类图:
            • 2、工厂模式
              • 抽象产品类:
                • 具体产品:
                  • 抽象工厂类:
                    • 具体工厂类:
                      • 测试类:
                        • 类图:
                        • 3、抽象工厂模式
                          • 抽象产品类:
                            • 产品族具体的抽象产品类:
                              • 具体产品类:
                                • 抽象工厂类:
                                  • 具体抽象工厂类:
                                    • 测试类:
                                      • 类图:
                                      领券
                                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档