您的位置:首页 > 其它

【设计模式】简单工厂模式

2018-07-10 20:09 101 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013781343/article/details/80990987

因为最近在研究spring的IOC(控制反转)里面涉及到了工厂设计模式,所以来学习一下

首先我们需要知道设计模式是什么!

简单的说就是:好用的套路,比如胶带沾过物品后遗留下来的胶痕,用风油精可以很快很方便的擦掉,这就是套路,别人总结出来的好用的经验,这就是设计模式!

那么我们知道,套路的使用都有一定的使用场景,在某些场景才好用,那么今天我们的场景就是:

假设我们开了一家水果店,最近越来越多的人都喜欢直接吃剥好皮,洗好,切好的果盘,那么我们的水果店就推出了这项服务,接下来用代码来实现一下
代码总的目录结构如下图

注意!接下来的代码是没使用简单工厂模式的代码
首先我们得抽象个基本的水果类出来,别的水果都从这里衍生出来,下面贴上代码

package cn.fruits;
/**
*基本水果类
*/
public abstract class BaseFruit {
protected String fruitName = "";

public void setFruitName(String fruitName) {
this.fruitName = fruitName;
}
//处理水果,因为每种水果处理方式不一样所以让继承子类自己去处理
public abstract void dealFruit();
//打包水果
public void packFruit(){
System.out.println(fruitName+" is packing ");
}
//付钱!
public void pay(){
System.out.println(fruitName+" is paying ");
}
}

接下来就是几个实现类,这里只贴一个水果的,其他的都一样

package cn.fruits;
/**
*@desc 苹果类 继承了BaseFruit
**/
public class Apple extends BaseFruit{

@Override
public void dealFruit() {
super.setFruitName("Apple");
System.out.println(fruitName + " is dealing");
}

}

然后我们有了水果,当然也得有个水果店,下面上水果店的代码

package cn.store;
/**
*水果店代码,只留了一个入口,体现了面向对象的封装性。。。。(自我认为的)
**/
public class FruitStore {

public static void main(String[] args) {
OrderFruit myOrder = new OrderFruit();
}

}

然后我们有了水果店,接下来得实现用户进店下订单功能 ,我们使用OrderFruit这个类来实现!下面上代码

package cn.store;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import cn.factories.SimpleFactory;
import cn.fruits.Apple;
import cn.fruits.BaseFruit;
import cn.fruits.Orange;
import cn.fruits.Pear;
/**
*@desc 用户下订单的类
**/
public class OrderFruit {
public OrderFruit(){
String fruitName = "";
BaseFruit fruit = null;
do{
fruitName = getInput();//获得用户输入
//!!!!!!!注意这里就是重点了--工厂模式要发挥的地方!!!!!!!
if("Apple".equals(fruitName)){
fruit = new Apple();
}else if("Orange".equals(fruitName)){
fruit = new Orange();
}else if("Pear".equals(fruitName)){
fruit = new Pear();
}else{
break;
}
fruit.dealFruit();
fruit.packFruit();
fruit.pay();
}while(true);

}
//获得用户输入
private String getInput(){
try {
System.out.println("please select fruit:");
BufferedReader buff = new BufferedReader(new InputStreamReader(System.in));
String type = buff.readLine();
return type;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "";
}
}

}

这就是我们初步写的代码,运行是可以运行,但是不知道各位发现了一个什么问题没有,假如,我店里又进了新的水果,我是不是就得在上面OrderFruit类的重点注意处添加又一个else if 来做处理,然后以后水果越多,加的越多,这样极其不合适,想一想每次我们都要改源代码,然后再编译,还有水果类都是我们自己new出来的,极其不适合以后的维护,那么我们如何改变呢,这时候我们就可以请出我们的简单工厂了,我只提供我要什么水果,工厂就将我要的水果类给我,这样就可以不用一直else if的加了,水果都是在工厂里获得,而不是直接写在代码里了!我们将获得水果的控制权交了出去(控制反转)那我们说加工厂就加工厂,工厂代码如下

package cn.factories;

import cn.fruits.Apple;
import cn.fruits.BaseFruit;
import cn.fruits.Orange;
import cn.fruits.Pear;
/**
* 这里的工厂就是把刚才下订单时候的那些if else拿过来 单独建立一个类用来
* 管理和维护那些水果
**/
public class SimpleFactory {
public static BaseFruit getFruit(String fruitName){
BaseFruit fruit = null;
if("Apple".equals(fruitName)){
fruit = new Apple();
}else if("Orange".equals(fruitName)){
fruit = new Orange();
}else if("Pear".equals(fruitName)){
fruit = new Pear();
}
return fruit;
}
}

然后刚才我们的订购类可以修改成如下样子

do{
fruitName = getInput();
fruit = SimpleFactory.getFruit(fruitName);
if(null != fruit){
fruit.dealFruit();
fruit.packFruit();
fruit.pay();
}else{
break;
}

}while(true);

这样我们要什么水果只要输入水果名,工厂负责把水果类给我们,就避开了刚开始要一直修改业务代码的问题。
可能有人还会说,那要是增加水果了,不是还得修改工厂类的代码吗?
那这样,我们其实可以将这些水果信息配置到xml之类的文件里,利用反射获得类,然后加载,这样其实也就是spring框架的ioc实现思路了,只不过spring是把水果当作了Bean对象来集中管理的!这样就可以实现低耦合,高内聚的原则了!
工厂模式还有抽象工厂模式,以后会整理出来,和大家交流!

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: