最近本打算把23种设计模式好好过一遍,无奈越看越懵,代码量不够,脑洞拿来凑。结合《HeadFirst 设计模式》和以往的学习,做一个总结。
所谓设计模式,其实就程序员前辈们总结出的编码设计经验。常用的可以分为3类,23种。
A:创建型模式:简单工厂模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式,单例模式。(6个)
B:结构型模式:外观模式、适配器模式、代理模式、装饰模式、桥接模式、组合模式、享元模式。(7个)
C:行为型模式:模版方法模式、观察者模式、状态模式、职责链模式、命令模式、访问者模式、策略模式、备忘录模式、迭代器模式、解释器模式。(10个)
但归根结底,使用设计模式的目的,是为了让代码具有良好的:维护性,扩展性,复用性。
面向对象加粗部分是我目前学习过的设计模式,工厂,单例,代理,装饰模式其实都讲的很多了,在这里我想总结一下策略模式,以学生上课来举例。
需求1:
我们打算做一款模拟学生活动的游戏,已知学校里的学生都要上课和运动。
1年级学生,学语文,跑步,
2年级学生,学语文,数学,跑步,
3年级学生,学语文,数学,英语,打篮球。
如何设计?
因为不同年级学生上课内容和运动的内容,都不是一直不变的,也许今年1年级学生只学语文,跑步,明年学校会额外教一门自然,或者取消跑步。所以说,针对上课和运动的行为,对于学生对象来说,这是很容改变的,所以要把行为抽离出来。
下面是我的类图
附上学生类代码
public abstract class Student {
public abstract void displayGradeName();
protected Go2ClassBehavior go2ClassBehavior;
protected SportBehavior sportBehavior;
public void setGo2ClassBehavior(Go2ClassBehavior go2ClassBehavior) {//可以自己设置上什么课
this.go2ClassBehavior = go2ClassBehavior;
}
public void setSportBehavior(SportBehavior sportBehavior) {//可以自己设置做什么运动
this.sportBehavior = sportBehavior;
}
public void performGo2class(){
go2ClassBehavior.listenClass();
}
public void performSport(){
sportBehavior.doSport();
}
}
public class FirstGrade extends Student{
public FirstGrade() {
go2ClassBehavior = new ChineseClass();
sportBehavior = new Running();
}
@Override
public void displayGradeName() {
System.out.println("我是一年级的学生");
}
}
public class SecondGrade extends Student{
public SecondGrade() {
go2ClassBehavior = new ChineseClass();
sportBehavior = new Running();
}
@Override
public void displayGradeName() {
System.out.println("我是二年级学生");
}
}
public class ThirdGrade extends Student{
public ThirdGrade() {
go2ClassBehavior = new ChineseClass();
sportBehavior = new Basketball();
}
@Override
public void displayGradeName() {
System.out.println("我是三年级学生");
}
}
附上行为类代码
public interface Go2ClassBehavior {
void listenClass();
}
public class ChineseClass implements Go2ClassBehavior {
@Override
public void listenClass() {
System.out.println("上语文课");
}
}
public interface SportBehavior {
void doSport();
}
public class Running implements SportBehavior {
@Override
public void doSport() {
System.out.println("跑步。。。。");
}
}
测试代码
public class StudentTest {
public static void main(String[] args){
Student s = new FirstGrade();
s.displayGradeName();
s.performGo2class();
s.performSport();
System.out.println("----------------------------");
s = new SecondGrade();
s.displayGradeName();
s.performGo2class();
s.setGo2ClassBehavior(new MathClass());
s.performGo2class();
s.performSport();
System.out.println("----------------------------");
s = new ThirdGrade();
s.displayGradeName();
s.performGo2class();
s.setGo2ClassBehavior(new MathClass());
s.performGo2class();
s.setGo2ClassBehavior(new EnglishClass());
s.performGo2class();
s.performSport();
}
}
运行结果:
我是一年级的学生
上语文课
跑步。。。。
----------------------------
我是二年级学生
上语文课
上数学课
跑步。。。。
----------------------------
我是三年级学生
上语文课
上数学课
上英语课
打篮球吧!!!
光是写例子还是觉得掌握不够深,今后还需要将这些设计模式运用在实际问题的解决中才能更好的掌握吧,最后还要附上面向对象设计的6大原则,都需要铭记于心。
- 1)单一原则:低耦合,高内聚。
- 2)开闭原则:一个对象对扩展开放,对内修改关闭。
- 3)里氏替换原则:在任何父类出现的地方都可以用它的子类来替代,其实就是说:同一个继承体系统中的对象应该有共同的行为特征。
- 4)依赖注入原则:要依赖于抽象,不要依赖于具体实现。
- 5)接口分离原则:不应该强迫程序依赖它们不需要使用的方法。
- 6)迪米特原则:一个对象应当对其它对象尽可能少的了解。其实就是说降低各个对象之间的耦合