这是看书学习的第三个模式,上一个礼拜学习了简易工厂模式和策略模式以及三个设计原则:单一职责原则、封闭开放原则以及依赖倒转原则(包括历史替换原则)。不看设计模式之前没感觉自己写的代码烂,看了一些设计模式之后感觉自己写的是什么垃圾玩意,虽然看的过程中既痛苦又快乐,不过为了未来的老婆能够生活的更好,那么就在秃头的路上继续努力。不过设计模式是需要反复看的,第一遍看到时候只能浅显的理解使用,灵活的运行还需要反复学习反复使用。加油!
穿衣打扮
90后大部分都可以说是跟着腾讯QQ一起长大的,其中在我小的时候,QQ装扮风靡了好一段时间,那么现在让你使用java程序编写一个换装的逻辑代码该怎么编写呢?
最笨的编写方式:在一个类中,每一种装扮方式我都写到一个方法里边,你需要哪种打扮组合,就自己调用装扮自己组合。恩,白学之前的原则了,想想看首先扩展就没考虑,明显的违反了封闭--开放原则,pass。
//装扮类
package zhuangShi;
public class Person1 {
private String name;
public Person1(String name) {
this.name = name;
}
public void WearTShire() {
System.out.print("T恤 ");
}
public void WearBigTrouser() {
System.out.print("垮裤 ");
}
public void WearSneaker() {
System.out.print("破球鞋 ");
}
public void WearSuit() {
System.out.print("西装 ");
}
public void WearTie() {
System.out.print("领带 ");
}
public void WearLeatherShoes() {
System.out.print("皮鞋 ");
}
public void Show() {
System.out.print(name+"着装为:");
}
}
//组合装扮输出
package zhuangShi;
public class Main1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Person1 p1 = new Person1("海朋");
System.out.println("第一种装扮为:");
p1.Show();
p1.WearBigTrouser();
p1.WearTShire();
p1.WearSneaker();
p1.WearTie();
}
}
先考虑开放封闭原则:在原有的基础上创建一个父类接口,并抽象一个装扮方法。并将每一个部位的装扮放到每一个子类中。每增加一种装扮,那么就新建一个子类实现下父类的装扮方法,不用去修改原有的类。
//父类接口
package zhuangShi;
public class Person2 {
private String name;
public Person2(String name) {
this.name = name;
}
public void show() {
System.out.println(name+"的着装为:");
}
}
//子类装扮1
package zhuangShi;
public class Tshirt implements Finery{
@Override
public void show() {
// TODO Auto-generated method stub
System.out.print("T恤 ");
}
}
//子类装扮2
package zhuangShi;
public class Leathershoes implements Finery {
@Override
public void show() {
// TODO Auto-generated method stub
System.out.print("皮鞋");
}
}
//组合输出装扮
package zhuangShi;
public class Main2 {
public static void main(String[] args) {
Person2 p2 = new Person2("赵冰");
System.out.println("第二种穿着打扮为");
Finery ts = new Tshirt();
Finery ls = new Leathershoes();
ts.show();
ls.show();
}
}
这下改的确实符合了开放--封闭原则,按照书上的意思是说这样直白的写法,就类似你脱光了,在众人面前一件一件的穿衣服(可能因为没有封装,把方法直接暴露在外边的原因,我暂时还不太理解,可能等第二次回头看这本书的时候会理解的更多,在此我不纠结了),在这里我们需要一种把所需的功能按照正确的顺序串联起来的方法,也就是装饰模式。装饰模式给我的一个感觉就是类似数据结构中的递归,将功能组装好后,从最上层一步步调用方法到最底层,然后在原路返回,不同的是递归是自己调用自己,装饰模式是一直调用不同类的方法。装饰模式需要一个接口、装饰对象(实现接口)、装扮抽象类(实现接口)、装扮类(继承装扮抽象类)
![](https://i-blog.csdnimg.cn/blog_migrate/34080cea5a5ae88bf4a0b1a894911e74.jpeg)
//接口,用于给实体对象装饰
package zhuangShi;
interface Component3 {
public abstract void operation();
}
//装饰对象,接下来会为他进行装饰
package zhuangShi;
public class ConcreComponent3 implements Component3{
@Override
public void operation() {
// TODO Auto-generated method stub
System.out.println("具体对象的操作");
}
}
//服饰抽象类
package zhuangShi;
abstract class Decorator implements Component3 {
protected Component3 component3;
public void SetComponent3(Component3 component3) {
this.component3 = component3;
}
@Override
public void operation() {
// TODO Auto-generated method stub
if(component3 != null) {
component3.operation();
}
}
}
//服饰类1
package zhuangShi;
public class ConcreteDecoratorA extends Decorator{
private String addState;
public void operation() {
component3.operation();
addState = "New State";
System.out.print("具体操作1 ");
}
}
//服饰类2
package zhuangShi;
public class ConcreteDecoratorB extends Decorator{
public void operation() {
component3.operation();
System.out.println("具体操作2");
}
public void addedBehavior() {
}
}
//主函数,装饰过程举例
package zhuangShi;
public class Main3 {
public static void main(String[] args) {
Component3 p1 = new ConcreComponent3();
ConcreteDecoratorA c1 = new ConcreteDecoratorA();
ConcreteDecoratorB c2 = new ConcreteDecoratorB();
c2.SetComponent3(p1);
c1.SetComponent3(c2);
c1.operation();
}
}
装饰模式灵活的运用了面向对象的多态特性,我刚开始看着点时候很头疼,多态用的少,虽然知道,但是代码理解起来还是比较困难的,不过倒是硬啃了下来,多多少少还是会了点最浅显的运用!