设计模式之工厂设计模式

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

前言

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

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

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

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

简单点

工厂及抽象工厂模式


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

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

1、简单工厂模式


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

抽象产品类:

手机

public abstract class AbstractPhone {
    public abstract void use();
}
具体产品类:

魅族手机和一加手机

public class Meizu extends AbstractPhone{
    @Override
    public void use() {
        System.out.println("正在使用魅族手机");
    }
}
public class OnePlus extends AbstractPhone {
    @Override
    public void use() {
        System.out.println("正在使用一加手机");
    }
}
具体工厂类:

生产手机的工厂

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;
        }
    }
}
测试类:
@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、工厂模式


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

需要加钱

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

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

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

抽象产品类:

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

具体产品:

同样是魅族和一加手机

抽象工厂类:
public abstract class AbstractPhoneFactory {
    public abstract AbstractPhone createPhone();
}
具体工厂类:

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

public class OnePlusFactory extends AbstractPhoneFactory {
    @Override
    public OnePlus createPhone() {
        return new OnePlus();
    }
}
public class MeizuFactory extends AbstractPhoneFactory {
    @Override
    public Meizu createPhone() {
        return new Meizu();
    }
}
测试类:
@Test
public void test02() {
    OnePlusFactory onePlusFactory = new OnePlusFactory();
    onePlusFactory.createPhone().use();

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

}

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

类图:

3、抽象工厂模式


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

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

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

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

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

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

抽象产品类:
public abstract class AbstractPhone {
    public abstract void use();
}
产品族具体的抽象产品类:

中端手机和旗舰手机

public abstract class AbstractMiddlePhone extends AbstractPhone {
    @Override
    public abstract void use();
}
public abstract class AbstractTopPhone extends AbstractPhone{
    public abstract void use();
}
具体产品类:

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

public class MeizuMiddlePhone extends AbstractMiddlePhone {
    @Override
    public void use() {
        System.out.println("魅族中端产品");
    }
}
public class MeizuTopPhone extends AbstractTopPhone {
    @Override
    public void use() {
        System.out.println("魅族高端旗舰");
    }
}
public  class OnePlusMiddlePhone extends AbstractMiddlePhone {
    @Override
    public void use() {
        System.out.println("一加中端产品");
    }
}
public class OnePlusTopPhone extends AbstractTopPhone {
    @Override
    public void use() {
        System.out.println("一加高端旗舰");
    }
}
抽象工厂类:
public abstract class AbstractFactory {
    public abstract AbstractPhone createMiddlePhone();

    public abstract AbstractPhone createTopPhone();
}
具体抽象工厂类:

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

public class MeizuFactory extends AbstractFactory {
    @Override
    public MeizuMiddlePhone createMiddlePhone() {
        return new MeizuMiddlePhone();
    }

    @Override
    public MeizuTopPhone createTopPhone() {
        return new MeizuTopPhone();
    }
}
public class OnePlusFactory extends AbstractFactory {
    @Override
    public OnePlusMiddlePhone createMiddlePhone() {
        return new OnePlusMiddlePhone();
    }

    @Override
    public OnePlusTopPhone createTopPhone() {
        return new OnePlusTopPhone();
    }
}
测试类:
@Test
public void test03() {
    OnePlusFactory onePlusFactory = new OnePlusFactory();
    MeizuFactory meizuFactory = new MeizuFactory();
    onePlusFactory.createMiddlePhone().use();
    onePlusFactory.createTopPhone().use();

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

}
类图:

二维码

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值