设计模式(1)创建型模式

总体来说设计模式分为三大类:创建型模式、结构型模式、行为型模式。

创建型模式

简单工厂模式

工厂类是整个模式的关键。它包含必要的判断逻辑,能够根据外界给定的信息知道创建那个类的实例,外部无需了解该对象是如何被创建和组织的。有利于软件体系结构化。由于工厂类集中了所有实例的创建逻辑,简单工厂模式的缺点也体现在工厂类上。

1
2
3
4
5
6
7
//Factory类

if( arg == "A" ){
return new FrescoLoader();
}else if( arg == "B" ){
return new GlideLoader();
}

可以明显的看到简单工程模式违反了开放-封闭原则(OCP)

工厂方法模式

工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象的工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

抽象工厂模式

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。

单例模式

单例模式是让一个类只创建一个实例,有“懒汉式”和“饿汉式”两种,有多种写法

第一种 :懒汉式线程不安全

1
2
3
4
5
6
7
8
9
10
11
12

public class Singleton {
private static Singleton instance;
private Singleton (){}

public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}

第二种:懒汉式线程安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton {  
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}

第三种:饿汉式

1
2
3
4
5
6
7
public class Singleton {  
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}

第四种:饿汉式变种

1
2
3
4
5
6
7
8
9
10
public class Singleton {  
private Singleton instance = null;
static {
instance = new Singleton();
}
private Singleton (){}
public static Singleton getInstance() {
return this.instance;
}
}

结构型模式

适配器模式

适配器模式把一个类的接口变化成以一种接口,让原来接口不匹配而无法在一起工作的两个类能够在一起工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class ListImpl{
void showList(){
System.out.println("showList");
}
}

interface Grid{
void showGride();
}

public class Adapter extends ListImpl implements Grid{

@Override
void showGrid(){
showList();
}
}

public static void main(String[] args){
Grid grid = new Adapter();
grid.showGrid();
}

装饰器模式

装饰器模式是动态给一个对象添加额外的职责

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
35
36
37
38
39
40
41
42
43
44
interface View{
void show();
}

class BaseView implements View{
public void show(){
System.out.println("i am baseview")
}
}

class ViewDecorator implements View{

private View view;
public ViewDecorator(View view){
this.view = view;
}

public void show(){
view.show();
}
}

class TextView extends ViewDecorator{

public TextView(View view){
super(view);
}

public void show(){
super();
System.out.println("i am textview")
}
}

class Main{

public static void main(String[] args){

BaseView view = new BaseView();
view = new TextView(view);
view = new Button(view);
view.show();
}
}

代理模式

代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/** 
* 抽象角色
* @author Administrator
*
*/
abstract public class Subject {
abstract public void request();
}


/**
* 真实角色
*/
public class RealSubject extends Subject{
public RealSubject(){

}

public void request(){
System.out.println("From real subject");
}
}
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
/** 
*
* 代理方法
*
*/
public class ProxySubject extends Subject{
private RealSubject realSubject; //以真实角色作为代理角色的属性

public ProxySubject(){

}

@Override
public void request() {
preRequest();

if(realSubject == null){
realSubject = new RealSubject();
}
realSubject.request();

postRequest();
}

private void preRequest(){
//something you want to do before requesting
}

private void postRequest(){
//something you want to do after requesting
}

}

外观模式(Facade Pattern)

不知道大家有没有比较过自己泡茶和去茶馆喝茶的区别,如果是自己泡茶需要自行准备茶叶、茶具和开水,如图1(A)所示,而去茶馆喝茶,最简单的方式就是跟茶馆服务员说想要一杯什么样的茶,是铁观音、碧螺春还是西湖龙井?正因为茶馆有服务员,顾客无须直接和茶叶、茶具、开水等交互,整个泡茶过程由服务员来完成,顾客只需与服务员交互即可,整个过程非常简单省事,如图1(B)所示。

在软件开发中,有时候为了完成一项较为复杂的功能,一个客户类需要和多个业务类交互,而这些需要交互的业务类经常会作为一个整体出现,由于涉及到的类比较多,导致使用时代码较为复杂,此时,特别需要一个类似服务员一样的角色,由它来负责和多个业务类进行交互,而客户类只需与该类交互。外观模式通过引入一个新的外观类(Facade)来实现该功能,外观类充当了软件系统中的“服务员”,它为多个业务类的调用提供了一个统一的入口,简化了类与类之间的交互。在外观模式中,那些需要交互的业务类被称为子系统(Subsystem)。如果没有外观类,那么每个客户类需要和多个子系统之间进行复杂的交互,系统的耦合度将很大,如图2(A)所示;而引入外观类之后,客户类只需要直接与外观类交互,客户类与子系统之间原有的复杂引用关系由外观类来实现,从而降低了系统的耦合度,如图2(B)所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Facade{

public void doSomeThing(ClassA a, ClassB b, ClassC c){
//...
}
}

class Main{

public static void main(String[] args){
Facade facade = new Facade();
facade.doSomeThing(...);
}
}