前言,相关联博客如下:
目录
1. 工厂模式
1.1 定义
什么是工厂设计模式:
根据名字来解析“工厂模式”, 首先工厂是用来生产产品的,而且所生产的产品都是工人们根据仓库中现有的很多材料加工出来的。以玩具工厂为例,这个玩具工厂可以生产出上百种玩具,工人们知道了解仓库中有什么材料,但他们不知道每天要加工生产什么种类的玩具,这个需要产品经理告诉他们每天去加工生产什么种类的玩具。
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
1.2 何时使用
当你无法预测要创建什么类型的对象时,而且创建这个对象十分复杂(如果用 new 就可以完成创建的对象,就不需要用工厂模式),就可以使用工厂模式。
2. 简单工厂方法
简单工厂模式只是工厂方法模式的一个弱化。(关于工厂方法模式,可以参考我的另一篇博客 Android 设计模式之工厂方法模式 )
在工厂方法模式中,我们有定义抽象工厂类,以及具体的工厂类,这两者的关系是一对多的关系。但是,如果只有一个具体工厂类的时候,我们完全可以将抽象工厂类去掉,这就是简单工厂模式。
3. 简单工厂模式实践案例Demo
1. 前提:今天是老板生日,他要请他的员工小明和老王吃饭,但老板不知道他们要吃什么,所以老板就问小明和老王你们想吃什么,小明说他想吃红烧肉,老王说他想吃酸菜鱼,可老板厨艺有限,所以只好出去饭店吃。
代码分析:吃饭,要做饭做菜,所以要创建对象-食物对象。老板不知道小明和老王要吃什么,也就是不知道要创建什么食物对象。小明要吃红烧肉老王要吃酸菜鱼,但老板不会做,也就是不会创建这些具体的食物对象。只好出去找饭店,让厨师来做红烧肉和酸菜鱼,也就是找工厂类来帮我们创建这些食物对象。(这就是工厂模式)
2. 到了饭店:到了饭店热情的服务员马上拿上端茶并递上菜单,看到菜单上有红烧肉和酸菜鱼,老板放心了,点了红烧肉和酸菜鱼再要了三碗米饭,很快就上菜了,三人开心的享用。
代码分析:饭店的厨房就是我们的食物加工工厂,但厨师要做什么菜,得我们点单了他才知道,也就是工厂类也需要我们告诉它需要创建什么对象。
3. 吃到一半:吃到一半的时候,小明突然意识到,今天是老板生日啊,怎么能没有蛋糕呢!喊来服务员,可服务员遗憾的告诉他,他们的厨师不会做蛋糕,所以没有蛋糕。
代码分析:饭店不能做蛋糕,所以工厂类也不是万能的,不是什么对象都能创建出来。
测试效果见(点击Gif图片查看):
all right! 让我们开始编写代码:
1. 创建一个食物接口:
public interface Food {
String get();
}
2. 创建具体的食物类来实现食物接口
比如:红烧肉类
public class Pork implements Food{
@Override
public String get() {
return "红烧肉";
}
}
还有:酸菜鱼类
public class Fish implements Food {
@Override
public String get() {
return "酸菜鱼";
}
}
还有:像蛋糕这样的创建不出来的未知类
public class UnknownFood implements Food {
private String mMenuName;
@Override
public String get() {
return "without " + mMenuName;
}
public UnknownFood(String menuName) {
this.mMenuName = menuName;
}
}
3. 创建我们的食物加工工厂类, 用来帮我们创建各种具体的食物。
public class FoodFactory {
public static Food getFoodByMenu(String menuName) {
if (menuName == null) {
return null;
}
if (menuName.equalsIgnoreCase("Pork")) {
return new Pork();
} else if (menuName.equalsIgnoreCase("Fish")) {
return new Fish();
}
return new UnknownFood(menuName);
}
}
4. 在我们的Activity中测试一下
public class SimpleFactoryPatternTestActivity extends AppCompatActivity {
private TextView mMenuTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_factory_pattern_test);
mMenuTv = findViewById(R.id.menu_tv);
final EditText menuEt = findViewById(R.id.menu_et);
menuEt.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
Food food = FoodFactory.getFoodByMenu(menuEt.getText().toString());
displayMenuFood(food.get());
hideKeyboard();
return true;
}
return false;
}
});
}
private void displayMenuFood(String menuFoodString) {
mMenuTv.setText(menuFoodString);
}
private void hideKeyboard() {
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
}
all right,到这一步,也就实现了如上图Gif所示的效果。
4.简单工厂模式的优缺点
4.1 优点
1. 用户需要对象时直接通过工厂类去实例化对象,不需要知道这些对象时如何创建出来的,利用系统结构优化。
4.2 缺点
1.当我需要增加一个产品的时候,就需要增加一个产品的具体类,还要去修改我的工厂类,增加了系统的复杂性。
2.违背了设计模式原则中的“开放封闭原则”(开放封闭原则:对扩展开放,对修改封闭),因为当你要添加一个具体的产品时,你需要去修改你的工厂类。