设计模式(二):简单工厂与策略模式

概述

在我看来简单工厂模式与策略模式是十分相似的,都是针对不同情况而产生不用的策略或是实体。因为十分相似的缘故,写在同一篇文章里比较合适。首先来看看简单工厂模式。

简单工厂模式

介绍

简单工厂属于创建型模式,也叫静态工厂方法模式,我们只需要知道要生产什么样的实体对象,不需要知道生产这个实体对象需要哪些具体的参数

作用

将实例化操作与使用实例对象的操作分开
避免显示指定,解耦。

具体实现

首先是工厂类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Factory{
//根据不用的要求生产生产什么样的产品
public static Product createProduct(String modeStr){
switch(modeStr){
case "A":
return new ProductA();
case "B":
return new ProductB();
case "C":
return new ProductC();
default:
return null;
}
}
}

各种产品实体肯定要实现Product接口啦:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
interface Product{
public void create();//被生产
}

... ...
class ProductA implements Product{
@override
public void create(){
Log.e(Tag,"创建了A产品呀");
}
}

... ...
class ProductB implements Product{
@override
public void create(){
Log.e(Tag,"创建了C产品呀");
}
}

... ...
class ProductC implements Product{
@override
public void create(){
Log.e(Tag,"创建了C产品呀");
}
}

在其他地方使用工厂类来生产产品

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class SimpleFactoryPattern {
public static void main(String[] args){
Factory mFactory = new Factory();

//客户要产品A
try {
//调用工厂类的静态方法 & 传入不同参数从而创建产品实例
mFactory.createProduct("A").create();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}

//客户要产品B
try {
mFactory.createProduct("B").create();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}

//客户要产品C
try {
mFactory.createProduct("C").create();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}

//客户要产品D
try {
mFactory.createProduct("D").create();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}
}
}

结果:

1
2
3
4
创建了A产品呀
创建了B产品呀
创建了C产品呀
没有这一类产品

小结

上面已经已经说了简单工厂模式只需关心我要什么样的产品,而不需要关系怎么生产这产品。能实现产品的操作与产品的创建解耦。这是它的优点。
同时,现在已经能生产ABC这些产品,但是一旦要新添加产品ProductD的话,就必须修改工厂类,违反设计模式的开闭原则,这也是它的缺点。
日常开发要视情况而定。

策略模式

开头说简单工厂模式与策略模式十分相似,到底哪些地方相似?

介绍

定义了一系列的算法策略,放在一个策略类中,根据不同情况而选择不同的策略(简单模式是根据不同的需要生产不同的产品)。

具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Context_SalesMan{
//持有抽象策略角色的引用
private Strategy strategy;
public SalesMan(String festival) {//根据不同的需求创建不同的策略
switch ( festival) {
case "A":
strategy = new StrategyA();
break;
case "B":
strategy = new StrategyB();
break;
case "C":
strategy = new StrategyC();
break;
}

}

public void SalesManShow(){//使用策略
strategy.show();
}
}

定义Strategy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
interface Strategy{
public void show();
}

... ...
class StrategyA implements Strategy{
override
public void show(){
Log.e(Tag,"使用了A策略");
}
}

... ...
class StrategyB implements Strategy{
override
public void show(){
Log.e(Tag,"使用了B策略");
}
}

... ...
class StrategyC implements Strategy{
override
public void show(){
Log.e(Tag,"使用了C策略");
}
}

在其他地方使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class StrategyPattern{
public static void main(String[] args){

Context_SalesMan mSalesMan ;

mSalesMan = Context_SalesMan SalesMan("A");
mSalesMan.SalesManShow();

mSalesMan = Context_SalesMan SalesMan("B");
mSalesMan.SalesManShow();

mSalesMan = Context_SalesMan SalesMan("C");
mSalesMan.SalesManShow();
}
}

结果:

1
2
3
Log.e(Tag,"使用了A策略");
Log.e(Tag,"使用了B策略");
Log.e(Tag,"使用了C策略");

小结

从上面的代码中可以看出根据不同情况来实例化具体的策略,假如我们不知道全部的策略,SalesMan(String festival)里面传入了“D”,这在后面肯定会引起异常错误。所以要必须知道所有的策略类。
当添加一个新的策略时,只需要新增一个具体的策略类即可,无须更改原有的代码。

总结

主要介绍了简单工厂模式和策略模式,其他设计模式可参看:
设计模式(一):简介及单例模式