设计模式

前段时间看了Head First设计模式,写了些记录。

策略模式(Strategy)

策略模式定义
定义算法簇,分别封装起来,让他们之间可以互相替换,让算法的变化独立与使用算法的客户
1. 利用接口,抽象类
从类中抽象出共同的行为,组合成一种行为接口
2. 找出应用中可能变化的地方,把他们独立出来,和稳定的代码区分开
3. 针对接口编程,而非针对实现编程
类中包含行为,但不需要直接实现行为。通过行为接口具体的实现,运行时选择
4. 封装行为,hasis好;多用组合,少用继承

代码:

public interface SomeBehavior{
    public void doSomething();
}

public class DoOne implements SomeBehavior{
    public void doSomething(){
    //do something
    }
}

public class DoTwo implements SomeBehavior{
    public void doSomething(){
    //do something
    }
}

public abstract class BaseClass{
    private SomeBehavior someBehavior;    
    public void doBehavior(){
        someBehavior.doSomething();
    } 
}
//以下可以继承其他具体类
public class UseClass extends BaseClass{
    public UseClass(){
        someBehavior=new DoOne();
    } 
    //doBehavior();//已经是DoOne的行为
}

观察者模式(Observer)

观察者模式定义了对象之间的一对多依赖,当一个对象改变状态是,他的所有依赖者都会收到通知并自动更新。

观察者模式类图:
《interface》—————————–>《interface》
Subject Observer
registerObserver() update()
removeObserver() |
notifyObserver() |
| |
| |
ConcreteSubject ConcreteObserver
registerObserver() update()
removeObserver()
notifyObserver()
getState()
SetState()

代码:

//订阅者
public interface Subject{
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObserver();
}
//观察者
public interface Observer{
    public void update();
}

具体类的实现可以通过ArrayList进行Observer的添加,维护和删除。具体的Observer的update可以根据具体的情况实现。

观察者模式有两种通知更新方式:
分发和获取。即更新的方式为被动和主动两种方式。
被动方式即通过notifyObserver()方式实现,遍历Observer列表顺序更新。
主动方式则是根据Observer的需要适时的向Subject进行更新请求,获取最新的数据。

Observer模式的应用:按钮的注册和事件分发。消息队列。

装饰者模式(Decorator)

当实体类过多时,继承可能可以解决问题,但是发生变动时会产生很多问题,基类加入的新功能并不适合所有子类。
类应该对扩展开放,对修改关闭。
装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更具有弹性的替代方案。
装饰者模式
装饰者Decorator继承自基类Component并包含一个Component用以保存具体Component实例。事实上通过组合可以减少继承使用的而生成的子类的个数。
缺点:使用者可能不能够理解大量的小类是通过包装实现。依赖特定的类型,从而出现错误。

工厂模式(Factory)

当需要实例化一个具体的类时,就会用到new。但是因此代码缺少了降低变化的可能性。

简单工厂:将创建实例的过程移到一个实例工厂里。让客户与具体的实例化代码解耦。

工厂方法:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法把实例化推迟到子类。

抽象工厂:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体的类。
抽象工厂是生产一系列相关类,强调的是有关系。

所有工厂模式都用来封装对象的创建。
工厂模式
代码示例:
简单工厂

public class Factory{
    public static Sample creator(int which){
        //getClass 产生Sample 一般可使用动态类装载装入类。
        if (which==1)
            return new SampleA();
        else if (which==2)
            return new SampleB();
    }
}
Sample sampleA=Factory.creator(1);

抽象工厂

public abstract class Factory{
    public abstract Sample creator();
    public abstract Sample2 creator(String name);
}

public class SimpleFactory extends Factory{
    public Sample creator(){
        .........
        return new SampleA;
    }
    public Sample2 creator(String name){
        .........
        return new Sample2A;
    }
}

public class BombFactory extends Factory{
    public Sample creator(){
        ......
        return new SampleB;
    }
    public Sample2 creator(String name){
        ......
        return new Sample2B;
    }
}

单件模式(Singleton)

单件模式:确保一个类只有一个实例,并提供一个全局访问点。

public class SampleClass{
    private static SampleClass sample;
    private SampleClass(){};
    public static SampleClass getInstance(){
        if(sample==null){
            sample=new SampleClass();
        }
        return sample;
    } 
}

问题:处理多线程可能出现多个实例。
处理办法:
1、加synchronized修饰。
2、急切模式,在声明sample是就实例化变量private static SampleClass sample=new SampleClass();

命令模式(Command)

重点是解耦,连设计程序的时候可以多想一想每个类的作用从而设计其功能,尽量可以流水作业,独立解耦。

“行为请求者”“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式(Command Pattern)
命令模式
Command:
定义命令的接口,声明执行的方法。
ConcreteCommand:
命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
Receiver:
接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
Invoker:
要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
Client:
创建具体的命令对象,并且设置命令对象的接收者。注意这个不是我们常规意义上的客户端,而是在组装命令对象和接收者,或许,把这个Client称为装配者会更好理解,因为真正使用命令的客户端是从Invoker来触发执行。

模式分析:
1.命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。
2.每一个命令都是一个操作:请求的一方发出请求,要求执行一个操作;接收的一方收到请求,并执行操作。
3.命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
4.命令模式使请求本身成为一个对象,这个对象和其他对象一样可以被存储和传递。
5.命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。

适用环境 :(远程API?)
1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
2.系统需要在不同的时间指定请求、将请求排队和执行请求。
3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4.系统需要将一组操作组合在一起(配合多线程),即支持宏命令。

状态模式(State)

状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态被封装成独立的类,通过状态机进行状态切换。

类图和策略模式相同,但是在context中的setstate方法可以被具体状态调用从而在已实现的状态之间流动。
状态模式
模式总结
优点
状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
所有状态相关的代码都存在于某个ConcereteState中,所以通过定义新的子类很容易地增加新的状态和转换。
状态模式通过把各种状态转移逻辑分不到State的子类之间,来减少相互间的依赖。
缺点
导致较多的ConcreteState子类
适用场景
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式来。
一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值