设计模式相关

六大原则

设计原则只是说设计更合理,不按照设计原则的套路来并不是代码错误或者实现不了功能。敲了这么多年的代码,要学会优雅。

1、开闭原则

一个模块、一个类或一个方法,应该对扩展开放,对修改关闭

比如一个方法,如果有新的内容需要判断,如果要修改这个类,那就是违背了这个原则。如果能够做到无缝扩展,那就是符合这个原则。

反例:

public class PieChart {
    public void display() {
        System.out.println("pie chart");
    }
}
public class BarChart {
    public void display() {
        System.out.println("bar chart");
    }
}
ChartDisplay 对外承接一切调用:
public class ChartDisplay {
    void display(int type){
        if(type == 1){
            PieChart pieChart = new PieChart();
            pieChart.display();
        } else if(type == 2){
            BarChart barChart = new BarChart();
            barChart.display();;
        }
    }
}

客户端调用:

public static void main(String[] args){
    ChartDisplay chartDisplay = new ChartDisplay();
    chartDisplay.display(1);
    chartDisplay.display(2);
}

这种情况,如果再加扩展WifiChart,那就要修改ChartDisplay类,对外接口不宜改动,不然哪里有幺蛾子也不晓得呀

正例:

抽象一个父类

public abstract class AbstractChart {
    public abstract void display();
}
PieChart、BarChart具体实现
ChartDisplay 对外承接一切调用:
public class ChartDisplay {
    AbstractChart chart;
    ChartDisplay(AbstractChart chart){ 这是个抽象类 verygood
        this.chart = chart;
    }
    void display(){
        chart.display();
    }
}

客户端调用,客户端你自己决定调用啥,不要接口方来区分

public static void main(String[] args){
    ChartDisplay chartDisplay = new ChartDisplay(new PieChart());
    chartDisplay.display();
    chartDisplay = new ChartDisplay(new BarChart());
    chartDisplay.display();
}

这样扩展一个WifiChart,只需要继承抽象父类,由客户端自己决定调用,不会修改ChartDisplay。

2、单一职责

一个类,应该只做一方面的事情。

反例:

public class Phone {
    void call(String number){}
    void close(){}
    void sendMessage(String number){}
    void reciveMessage(){}
}

一个电话,包括打电话,发短信,如果还有聊微信、聊QQ、邮箱,那这个类就是一个大杂烩。

正例:

public class Call {
    void call(){}
    void close(){}
}
public class Mesage {
    void send(){}
    void receive(){}
}
public class Phone {
    private Call call;
    private Mesage mesage;

    public Call getCall() {
        return call;
    }

    public void setCall(Call call) {
        this.call = call;
    }

    public Mesage getMesage() {
        return mesage;
    }

    public void setMesage(Mesage mesage) {
        this.mesage = mesage;
    }
}

Phone是对外接口,这里看起来又违背了开闭原则,不过Call 和 Message实在是抽象不出来了。大概是这个意思就行,Phone看起来没那么杂乱了。至少不都实现,只用Call的只用Call,只用Message的只用Message。

3、里氏替换原则

子类可以扩展父类的功能,但不能修改父类已有的功能。让我想起了模板模式,模板方法不要改。

比如,客户,vip客户,普通客户,而发邮件是vip和普通都一样的。那就客户里面定义好发邮件功能,vip和普通直接拿来用不要修改。修改当然可以,但是通用功能没必要修改。要优雅。

4、依赖倒转原则

没太看明白

5、接口隔离原则

理解为接口分离,接口里面功能尽量少,可以创建多个接口。与单一职责差不多,单一职责是说实现,接口隔离是功能越少越好,灵活。

6、迪米特原则

听起来像是limit,一个类要对其他类知道越少越好,只管引用,不管实现。如果一辆车开动类,包含引发发动机、检测油箱、检测轮胎、开动雨刷,就对其他类知道的太多了。如果修改开动类,增加停车方法,就会修改其他那几项。

这时候如果独立出来一个控制类,增加停车方法,只需要修改增加控制类,不需大改对外的开动类。

 

二十三

创建型:

    1、单例;2工厂方法;3抽象工厂;4创造者;5原型

结构型:

    1、适配器;2桥接;3装饰;4组合;5享元;6代理;7外观

行为型:

    1、观察;2访问;3中介者;4解释器;5迭代器;6状态;7命令;8策略;9备忘录;10职责链;11模板方法

1、适配器模式:两个不相同的类,集合到一起工作。比如,一个接口FacadeA需要调用ClassB的方法funC(),则设计一个适配器类AdapterAB implement FacadeA extentd ClassB,这样就可以使用super.funC()了,而不是在FacadeA的实现类FacadeAImpl里面调用ClassB对象的funC()方法。

好处就是:想增加多少个适配器就增加多少个。不用修改FacadeAImpl里面的方法,符合开闭原则。

2、装饰器模式:使用ClassB,为ClassA进行功能加强。最典型的应用为:BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(System.in)); IO输入里面有很多装饰器模式的思想,这里的BufferedReader就是InputStreamReader的装饰器,为InputStreamReader新添加了Buffer功能。

3、代理模式:FacadeA有实现类FacadeAImpl,用户可以直接调用FacadeA的实现类方法,但是如果想要在方法之间做点什么,所有的用户们则都需要自己重复造轮子。所以如果有个代理类,承包了在调用FacadeA方法funC()之前和之后的操作,就免去了用户们的额外重复工作。

      想对被代理的功能做点额外的事,又不想侵入代码----静态代理为在代码中调用对象方法,这样保证了遵循开闭原则,但是每次有改动的需要(新增接口)还得改动代理类;而动态代理,可以在调用代理类的时候,才指定调用的对象,完全不需要重写代理类,可以用实现Proxy和CGLib的方法。

4、

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值