设计模式学习心得

学习到现在的主要问题是没有进行例子的完美历练,说白了,就是没动手亲自的试试,写写对应的代码,理解一下主要的设计思想,这个应该是学习设计模式我最重要的地方,那么现在针对之前学习的设计模式做一个总结和回顾吧

0.设计模式分析规律
在讲解这个设计模式之前,我们应该学习到设计的原则,1.分析程序中变化的位置,针对变化的位置进行封装隔离
分析是对鸭子的叫声和会飞进行了特殊的隔离,因为这两种行为是特殊于其他普通鸭子的行为,这里考虑的就是封装这个变化
第一种角度:我们考虑之前的行为都是采用继承的关系,但是这样所有的子类都具有叫声和飞行的行为了,不能这样用
第二种角度:我们采用接口的形式,让父类实现这两个接口,其他子类进行覆盖,有的鸭子就覆盖,没有就不覆盖,这样的写法带来的问题是,以后要是有新的行为加入进来,子类和父类还要修改
引入第二个设计原则:针对接口编程,而不是实现编程
那么这样考虑以后,有了另一种角度
第三种角度:设计两个接口,一个叫,一个飞行,然后写各自的实现类,叫声类,和飞行类,将这两个类的接口行为组合在鸭子的父类中,即鸭子父类持有这两个行为接口,
父类写两个方法,使得有些鸭子可以请求叫方法,有的可以请求飞行的方法,让子类来传递飞行和叫的方式,比如:有的“呱呱叫” 有的不叫,有的飞行有的像火箭一样
为了实时修改这两个类,加入设置的set方法动态修改叫和飞行的行为

问题:这里父类也有了叫和飞行的行为,是不是违背了之前说的不用继承,特殊行为应该在某些子类上
问题:这里要考虑我们之前说的变化是什么?1,叫和飞行的行为区别于一般鸭子,只是这样的一种,2.叫和飞行的行为有一类这样的行为了

1.策略设计模式
上面的例子貌似是特意为策略设计模式制定的,那么我们该怎么样分析这个模式
算法簇的替换,而不影响其他的行为

模式结构:一个接口,多个实现类,用这个接口来维护一种或多种行为,不同的实现类相互替换(非典型的策略模式)

//飞行接口
public interface FlyBehavor{
void fly();
}
//飞行行为类
public RebotFly implements FlyBehavor{

public void fly(){
//添加自身的非行为
}
}

public class Duck{

private FlyBehavor mFlyBehavor;

public Duck(FlyBehavor mFlyBehavor){
this.mFlyBehavor = mFlyBehavor;
}

public void performFly(){
mFlyBehavor.fly();
}
}

思考:

 1.典型的策略模式的结构和适用场景

   策略模式典型是Context(场景),Strategy(接口策略),策略子类,场景对接口策略进行持有,利用子类替换达到不同算法的目的

   适用场景:用同一个方法,来计算不同的业务关系,制定不同算法 

  2.适用构造方法传参,还是适用setter方式,有什么区别,各有什么优缺点?

      构造方法在初始化定义传入参数,setter方式是改变当前对象的持有属性,setter用于一个对象多次改变自身属性

2.状态模式

  状态模式是对象通过改变自身的属性,来改变其行为(方法),达到消除条件判断语句的作用

  状态模式的结构重点:

  ContextState(对象场景),State(对象持有状态属性),状态子类,状态子类和策略子类的区别就是状态子类通过方法传递入参ContextState来修改本身状态

 1   public class ContextState{
 2      public State mState;
 3      public int hour;//状态属性
 4      public void setState(State state){
 5          mState = state;
 6      }
 7      public void request(){
 8        mState.handle(this)
 9     }
10   }
11 
12    public interface State{
13     void handle(ContextState  state); 
14   }
15   
16   public StateA implement State{
17     public void handle(ContextState context){
18       //这里用来改变当前对象的状态
19        context.state = new StateB();
20          if(context.hour < 12){
21               //上午工作很充实
22          }else{
23               //不符合条件继续向下分发
24                context.setState(new StateB());
25               context.request();
26         }
27        }  
28    }  
29   public StateB implement State{
30     public void handle(ContextState context){
31       //这里用来改变当前对象的状态
32        context.state = new StateA();
33          if(context.hour < 12){
34               //上午工作很充实
35          }else{
36               //不符合条件继续向下分发
37                context.setState(new StateA());
38               context.request();
39         }
40        }  
41    }         

以上代码仅供参考

思考:

 1.状态模式必须有相应的状态属性吗?这种状态可以用枚举来代替吗?

 2.状态模式适用的场景有哪些,是通过什么样的出发点来使用状态模式的?

   状态模式的出发点就是对象本身状态的改变来修改行为,那这种状态可以是多个吗?

 

3.观察者模式
相关例子的引入是做一个气象发布器,将系统发布的气象信息显示在多个公告栏上
多个公告栏的实时更新是核心部分,变化的位置是在哪里?比如添加或减少一个信息公告栏,信息公告栏的主要功能变化,公告栏的外观的变化,发布信息的数据结构变化(接入其他系统的气象信息)
之前的设计方式是否合理,这个是根据OO设计经验来完成的,要多积累才行
之前的设计是在气象更新器中写死气象信息更新的类,有信息更新,就发送给公告栏,这样的设计有什么问题吗?
问题1.如果多个公告栏中有一个不用了,这样我们要手动删除代码,测试,
问题2.气象加入了新的公告信息,加入新的字段,比如温度,湿度,风向,级别
问题3.OO设计思想是什么?为什么要这样用?

问题1.违反了OO设计原则:对扩展开发,对修改关闭
问题2.将所有的类统一成一个整体
问题3.设计类交互的松耦合而努力

模式结构:
"推"消息
被观察者(气象站) 观察者(公共栏)
拥有对所有观察者的引用(集合) 提供一完整的更新接口(update)
信息更新(遍历,将气象信息传递给公共栏)
-----------------------------------------------------------------------------------
"拉"消息
被观察者(气象站) 观察者(公共栏)
拥有对所有观察者的引用(集合) 提供一完整的更新接口(update(obseverable,obj)
信息更新(遍历,将气象信息传递给公共栏)

观察者模式主要的结构

一个被观察者,多个观察对象,当被观察者改变时通知其他观察对象作出改变(一个对象内部状态改变的同时通知其他对象改变)

被观察者拥有观察者的集合,并且拥有添加和移除,通知方法,观察者有抽象的更新数据接口

思考:

1.怎样实现一个对象既是观察者也是被观察者,在Java中有系统库可以实现吗?

2.观察者模式适用的场景有哪些?

 

4.装饰模式

  作用:对一个对象已有功能动态的添加更多功能的一种方式

  优点:有效的区分类的核心功能和装饰功能,在特殊时间或特定时期给核心功能添加部分装饰

  代码结构:

  一个通用的装饰接口,装饰类及其子类,

//接口
public interface Compent{
  void Operation(); 
}
//装饰类
public Decorate implement Compent{
  protected Compent mCompent;

  public void setCompent(Compent compent){
      mCompent = compent;
  }

  public void Operation(){
    mCompent.Operation();
   }
}
//装饰类的子类
public DecorateA extends Decorate{

 private String msg;
  public void Operation(){
   //添加文案输出功能
   System.out.println(msg);
   super.Operation();
  }
}
//特殊情况下,装饰类和装饰子类可以进行合并

 

posted @ 2016-12-01 15:48  lichl  阅读(2209)  评论(0编辑  收藏  举报