一、局部化修改——目标是减少由某个变更直接影响的模块的数量;

1、预期期望的变更(expected changes ):

确保canVote() 方法返回true或者false, 同时你也能写一个测试用来验证这个方法抛出的IllegalArgumentException异常。

复制代码
public class Student {
 
  public boolean canVote(int age) {
      if (i<=0) throw new IllegalArgumentException("age should be +ve");
      if (i<18) return false;
      else return true;
  }
}
复制代码

Guava类库中提供了一个作参数检查的工具类--Preconditions类,也许这种方法能够更好的检查这样的参数,不过这个例子也能够检查

2、维持语义一致性(semantic coherence ):

3、泛化模块(Generalize the module ):

4、限制选择参数(Limit possible options ):

二、防止连锁反应——目标是限制对局部化的模块的修改,以防止对某个模块的修改间接地影响到其他模块;

尽量维持现有接口或类的名字等不变,把要改动的模块尽量降到最低。推迟绑定时间在我的系统中还没有体现出来。

维持语义的一致性是保证模块中不同责任之间可以协同工作,不要太多的依赖于其他的模块。

1、信息隐藏(Hide information ):

2、维持现有接口(Maintain existing interfaces ):

3、限制通信路径(Restrict communication paths ):

4、使用仲裁者(Use an intermediary ):

 采用迪米特法则可以有效防止连锁反应:

例子:

在美国电影《教父》中,教父如果为了除掉对手,会亲自动手吗?肯定不,教父会安排手下人处理。教父这样位高权重的人,会直接跟杀手安排任务吗?一般不会,他会跟手下的心腹说明,然后由手下人去执行。

这样一来,我们看看,先看看三个普通角色,被杀的人Person,杀手Killer,心腹CoreMember,如下:

复制代码
/**
 * 某个人
 * @author ljtyzhr
 *
 */
public class Person{
    public String name;
}
 
/**
 * 杀手
 * @author ljtyzhr
 *
 */
public class Killer{
     public void kill(Person someone){
         System.out.println(someone.name+"被杀死了");
     }
}
 
/**
 * 教父身边的核心人员
 * 
 * @author ljtyzhr
 *
 */
public class CoreMember{
    private Killer killer;
}
复制代码

事实上,核心人员直接与杀手打交道,教父只会与心腹打交道,如此,关系应该如下:

复制代码
/**
 * 教父身边的核心人员
 * 
 * @author ljtyzhr
 *
 */
public class CoreMember{
    private Killer killer;
    public void kill(Person someone){
              killer.kill(someone);
    }
}
复制代码

家父持有对核心人员的引用,如下:

复制代码
/**
 * 教父
 * @author ljtyzhr
 *
 */
public class GodFather{
     CoreMember coremember;
     
     public void kill(Person someone){
           Killer killer = new Killer();
           killer.kill(someone);
     }
}
复制代码

 实现区块的隔离,使得模块之间具有独立性

三、延迟绑定时间——目标是控制部署时间并允许非开发人员进行修改。

1、运行时注册(Runtime registration):

2、配置文件(Configuration files):

3、多态(Polymorphism):

4、组件更换(Component replacement ) :

5、遵守已定义的协议(Adherence to defined protocols) :

延时0.5秒后发送一个网络请求,首先想到了handler,结果出现这么一个错误,解决方案很简单,就是在线程里调用Looper.prepare(),然后调用Looper.loop()就可以了

复制代码
private void sendMessageToClient(final StringBuilder s){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sendToClient.sendDataToClient(s,clientSocketAddress);//网络请求必须在子线程
            }
        }).start();

    }
复制代码

猜你喜欢

转载自www.cnblogs.com/zjm15511858030/p/12464865.html