❤❤❤武汉加油,中国加油!❤❤❤
疫情严重,口罩万金难求。本节将使用口罩作为【简单工厂|普通工厂|抽象工厂】的例子。
简介:
工厂模式可以分为三种模式:
1、简单工厂模式。
2、普通工厂模式。
3、抽象工厂模式。
这三种模式从上到下逐步复杂、抽象。三者可以独立使用,也可混合使用,没有绝对的谁好只有谁最合适,切忌为了设计模式而设计模式。
简单工厂:
工厂如其名,简单工厂是真的简单。代码简单、结构简单、对象的创建简单成为简单工厂的特点。严格来说,简单工厂并不属于设计模式的范畴,但由于简单工厂和普通工厂、抽象工厂有一定的关联,所以简单的提及一下简单工厂。
产品代码:
/**
* <p>
* 基类Mask
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public interface Mask {
// 打开口罩包装
void open();
// 使用口罩
void wear();
// 丢弃口罩
void discard();
default void use() {
open();
wear();
discard();
}
}
/**
* <p>
* 一次性口罩
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class DisposableMask implements Mask {
@Override
public void open() {
System.out.println("open DisposableMask");
}
@Override
public void wear() {
System.out.println("wear DisposableMask");
}
@Override
public void discard() {
System.out.println("discard DisposableMask");
}
}
/**
* <p>
* N95口罩
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class N95Mask implements Mask {
@Override
public void open() {
System.out.println("open N95Mask");
}
@Override
public void wear() {
System.out.println("wear N95Mask");
}
@Override
public void discard() {
System.out.println("discard N95Mask");
}
}
/**
* <p>
* 防毒口罩
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class GasMask implements Mask {
@Override
public void open() {
System.out.println("open GasMask");
}
@Override
public void wear() {
System.out.println("wear GasMask");
}
@Override
public void discard() {
System.out.println("discard GasMask");
}
}
工厂代码:
/**
* <p>
* 生产口罩的工厂
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class Factory {
public static Mask produce(String type) {
if ("DisposableMask".equals(type)) {
return new DisposableMask();
} else if ("N95Mask".equals(type)) {
return new N95Mask();
} else if ("GasMask".equals(type)) {
return new GasMask();
}
return null;
}
}
使用:
public class Main {
public static void main(String[] args) {
Mask mask = Factory.produce("N95Mask");
mask.use();
}
}
控制台:
从Factory类中的produce方法中我们可以发现,produce方法根据参数type来生成相应的Mask。假如工厂引进了生产N90Mask的技术,此时就必须要修改produce方法,这违背了开闭原则。
普通工厂:
前面提到的简单工厂,只适合在结构简单的情况下使用,所以这里引入了普通工厂,使用普通工厂之后,当需要拓展工厂时,就不需要更新原有工厂中的代码了。
工厂代码:
/**
* <p>
* Factory基类
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public interface BaseFactory {
Mask produce();
}
/**
* <p>
* 一次性口罩工厂
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class DisposableMaskFactory implements BaseFactory {
@Override
public Mask produce() {
return new DisposableMask();
}
}
/**
* <p>
* 创建N95口罩的工厂
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class N95MaskFactory implements BaseFactory {
@Override
public N95Mask produce() {
return new N95Mask();
}
}
/**
* <p>
* 防毒面具工厂
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class GasMaskFactory implements BaseFactory {
@Override
public Mask produce() {
return new GasMask();
}
}
使用:
/**
* <p>
*
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class Main {
public static void main(String[] args) {
BaseFactory factory = new N95MaskFactory();
Mask mask = factory.produce();
mask.use();
}
}
控制台:
简单工厂与普通工厂的不同:
先回顾一下简单工厂,简单工厂中有一个Factory类,根据这个类的produce(type)来实例化对象,而在普通工厂中额外创建了多个Factory继承于BaseFactory,将Mask的实例化转移到子类中,这是一个非常重要的变化,如此一来每当我们需要拓展另一种Mask的时候,我们只需要创建一个新的Factory并继承于BaseFactory,即可应对需求的变化。普通工厂非常符合开闭原则。
抽象工厂:
以上述例子为例,在普通工厂中,产品只有一种类别,即一次性口罩、N95口罩、防毒口罩。顺便提一下,在本次冠状病毒疫情中,中华民族可谓万众一心,无论是在国内的百姓还是海外留学生和华侨都尽可能的购买医疗用品捐助于一线医院,这真的很让人感动。虽然捐助的口罩非常多,但是其中有部分口罩达不到医用级别。这里咱们使用这个例子来探讨抽象工厂。
不妨我们为口罩再添加一个类别——使用等级,即民用和医用。这样口罩拥有了两种分类方式:①按照口罩使用等级,医用和民用。②按照口罩的类型,一次性口罩、N95口罩、防毒口罩。
一、引入两个新概念
产品等级结构:即产品的继承结构。例如:抽象产品(父类)是口罩,具体产品(子类)是一次性口罩、N95口罩、防毒口罩等。二者之间构成一个产品等级结构。
产品族:共一个工厂生产的产品,位于不同产品等级结构中的一组产品。比如民用产品工厂 不仅生产医用一次性口罩,还生产医用N95口罩、医用防毒口罩等。
二、结构图
产品代码:
/**
* <p>
* 基类Mask
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public interface Mask {
// 打开口罩包装
void open();
// 使用口罩
void wear();
// 丢弃口罩
void discard();
default void use() {
open();
wear();
discard();
}
}
/**
* <p>
* 民用一次性口罩
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class DisposableMask_C implements Mask {
@Override
public void open() {
System.out.println("open DisposableMask_C");
}
@Override
public void wear() {
System.out.println("wear DisposableMask_C");
}
@Override
public void discard() {
System.out.println("discard DisposableMask_C");
}
}
/**
* <p>
* 民用N95口罩
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class N95Mask_C implements Mask {
@Override
public void open() {
System.out.println("open N95Mask_C");
}
@Override
public void wear() {
System.out.println("wear N95Mask_C");
}
@Override
public void discard() {
System.out.println("discard N95Mask_C");
}
}
/**
* <p>
* 民用防毒口罩
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class GasMask_C implements Mask {
@Override
public void open() {
System.out.println("open GasMask_C");
}
@Override
public void wear() {
System.out.println("wear GasMask_C");
}
@Override
public void discard() {
System.out.println("discard GasMask_C");
}
}
/**
* <p>
* 医用一次性口罩
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class DisposableMask_M implements Mask {
@Override
public void open() {
System.out.println("open DisposableMask_M");
}
@Override
public void wear() {
System.out.println("wear DisposableMask_M");
}
@Override
public void discard() {
System.out.println("discard DisposableMask_M");
}
}
/**
* <p>
* 医用N95口罩
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class N95Mask_M implements Mask {
@Override
public void open() {
System.out.println("open N95Mask_M");
}
@Override
public void wear() {
System.out.println("wear N95Mask_M");
}
@Override
public void discard() {
System.out.println("discard N95Mask_M");
}
}
/**
* <p>
* 医用防毒口罩
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class GasMask_M implements Mask {
@Override
public void open() {
System.out.println("open GasMask_M");
}
@Override
public void wear() {
System.out.println("wear GasMask_M");
}
@Override
public void discard() {
System.out.println("discard GasMask_M");
}
}
工厂代码:
/**
* <p>
* Factory基类
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public interface BaseFactory {
Mask produceDisposableMask();
Mask produceN95Mask();
Mask produceGasMask();
}
/**
* <p>
* 生产民用口罩的工厂
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class CFactory implements BaseFactory {
@Override
public Mask produceDisposableMask() {
return new DisposableMask_M();
}
@Override
public Mask produceN95Mask() {
return new N95Mask_M();
}
@Override
public Mask produceGasMask() {
return new GasMask_M();
}
}
/**
* <p>
* 生产医用口罩的工厂
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class MFactory implements BaseFactory {
@Override
public Mask produceDisposableMask() {
return new DisposableMask_C();
}
@Override
public Mask produceN95Mask() {
return new N95Mask_C();
}
@Override
public Mask produceGasMask() {
return new GasMask_C();
}
}
使用:
/**
* <p>
*
* </p>
*
* @author 1999single
* @since 2020-02-22
*/
public class Main {
public static void main(String[] args) {
BaseFactory factory = new MFactory();
Mask disposableMask = factory.produceDisposableMask();
Mask n95Mask = factory.produceN95Mask();
Mask gasMask = factory.produceGasMask();
disposableMask.use();
n95Mask.use();
gasMask.use();
}
}
控制台:
假如在现实生活中有一家医院需要采购医用口罩,只需要初始化MFactory并调用produce方法,即可获得到需要的医用口罩。 具体的工厂中所能实例化的产品的集合为一个产品族,一个产品族里的元素之间的关系为产品等级结构。
假如企业打算投入生产军用一次性口罩、军用N95口罩和军用防毒面具,则可以新建一个Factory类并继承于BaseFactory,编写实例化口罩对象的方法即可完成扩展。