正文共 2763 字
阅读时长:5-7 min
问题引入:
慵懒的假期,躺在沙发上的你突然想吃苹果。
苹果,从哪里来呢?
1 出门去种植,等待结果
2 去超市购买
想了想,还是去超市购买方便,自己种出来只能给儿子孙子吃了。
在这个问题中,沙发上的你,是苹果对象的使用者。超市(果农场)是苹果对象的生产者,可以理解为工厂。
如果明天又想吃菠萝,草莓,怎么办呢?从工厂拿,多方便。
那么拿的时候就要判断你想要的水果名字,找到并返回该水果对象。
将这个过程用传统代码表示,客户端:
代码语言:javascript复制public Fruit getFruit(String fruitName){
Fruit fruit;
if("apple".equals(fruitName)){
fruit = new AppleFruit();
}else if("pineapple".equals(fruitName)){
fruit = new PineappleFruit();
}else if("Strawberry".equals(fruitName)){
fruit = new StrawberryFruit();
}
return fruit;
}
......
在一个主函数中完成所有的功能,水果类,调用关系等。当有新水果增加或去掉水果时,需要重新修改这一大段代码。
接下来就来看看一种设计模式 :
简单工厂模式:
它是一种创建型模式。创建型模式:只关注对象的创建过程。
创建什么(what)
由谁创建(who)
何时创建(when)
将对象的创建和使用分离,客户端在使用对象时,无需关心对象创建的细节过程。在一定程度上降低系统耦合度。
简单工厂模式定义:
定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。
角色:
Factory 简单工厂
Product 抽象产品
ConcreteProduct 具体产品
要点:需要什么?只需要传入一个正确的参数,就可以获取想要的对象,而无需知道其创建细节。
上述需求的简单工厂模式下的类图:
水果接口:
只需要定义一个抽象的水果接口,具体的水果,由具体的水果类来完成。
代码语言:javascript复制package com.sample.simplefactorypattern;
public interface Fruit {
public void tipInfo();
}
具体水果实现类:
该实现类实现 Fruit 接口,并在自己的方法中完成相应的算法操作。
即每一个类都实现自己的 tipInfo 方法。
代码语言:javascript复制package com.sample.simplefactorypattern;
public class AppleFruit implements Fruit {
@Override
public void tipInfo() {
System.out.print("山东红富士");
System.out.println("苹果已送达");
}
}
package com.sample.simplefactorypattern;
public class PineappleFruit implements Fruit {
@Override
public void tipInfo() {
System.out.print("酸酸甜甜的");
System.out.println("菠萝已送达");
}
}
package com.sample.simplefactorypattern;
public class StrawberryFruit implements Fruit {
@Override
public void tipInfo() {
System.out.print("红里透蜜的");
System.out.println("草莓已送达");
}
}
简单工厂类:
在工厂中,需要对客户端传入的参数进行比较核对,查看工厂是否能生成相应的对象。如果可以,则返回对应对象。
同时缺点显而易见,当具体产品类多时,出现大量 if... else 循环。
代码语言:javascript复制package com.sample.simplefactorypattern;
public class SimpleFruitFactory {
public static Fruit createFruit(String name){
if("apple".equalsIgnoreCase(name)){
return new AppleFruit();
}else if("pineapple".equalsIgnoreCase(name)){
return new PineappleFruit();
}else if("strawberry".equalsIgnoreCase(name)){
return new StrawberryFruit();
}else {
return null;
}
}
}
客户端类:
在客户端中,只需要传入一个参数,通过简单工厂类,调用生产(创造)对象的方法,就可以获取到相应对象。
代码语言:javascript复制package com.sample.simplefactorypattern;
public class Client {
public void getFruit(String name){
Fruit fruit;
fruit = SimpleFruitFactory.createFruit(name);
if(fruit != null) {
fruit.tipInfo();
}else{
System.out.println("该水果已售完,请等待。");
}
}
public static void main(String[] args) {
Client client = new Client();
client.getFruit("apple");
client.getFruit("pineapple");
client.getFruit("strawberry");
client.getFruit("banana");
}
}
运行效果:
项目目录:
当有新的水果种类需求时,通过新的类实现 Fruit 接口即可,在简单工厂类 simpleFruitFactory 类中仍然有大量的 if ... else 判断,客户端在调用时,只需要指定一个参数就可以。
该模式并不完全符合开闭原则,比传统代码有了独立结构,没有在客户端进行复杂修改。
注:简单工厂模式并不属于常用的 23 种设计模式。
简单工厂模式优点:
实现了对责任的分割,提供了专门的工厂类用于创建对象,客户端只消费产品;
客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类对应的参数即可。对于复杂的类名,可以简单的符号代替,减少记忆量。
简单工厂模式缺点:
工厂类是该模式下的核心,一旦崩溃,全局皆输;
增加了系统中类的个数,一定程度上加大了维护难度;
不利于系统扩展,一旦添加新产品,需要修改工厂类,不符合开闭原则;
对了,他并不完美,因为还有他的升级版,工厂模式,我们下篇文章见。
好了我的读者朋友,简单工厂设计模式介绍到这里,如有疑问,欢迎与我沟通交流。
感谢阅读,感谢陪伴。还没关注的,记得关注➕一下。
表情包来源于网络,侵删。谢谢。