常见的设计模式(模板、策略、装饰器)
1、模板模式
模板方法,顾名思义,就是给你一个模板的方式,你只需要按照这个模板执行就可以了。在模板模式中,设计一个抽象类,在抽象类中设计我需要声明的一些通用的方法,然后以组织在一个方法中,按照我自己想要的顺序去组织,而子类只需要继承这个抽象类,对其中的抽象方法进行具体的实现即可。这种模板模式是属于一个行为型模式。
注意一下:模板方法是需要添加final关键字的,因为这个是不能被修改或重写的。
具体的代码实现:
/** * 模板模式(以抽象类的方式实现设计) */ public abstract class Game { public abstract void function1(); public abstract void function2(); public abstract void function3(); public final void executeFunction() { function1(); function2(); function3(); } }
public class Main { public static void main(String[] args) { zhangsan zhangsan = new zhangsan(); zhangsan.executeFunction(); lisi lisi = new lisi(); lisi.executeFunction(); } } 结果: 张三 --- function1 张三 --- function2 张三 --- function3 李四 --- function1 李四 --- function2 李四 --- function3 Process finished with exit code 0
2、策略模式
在策略模式中,一个类的行为是可以在程序运行时做出动态改变的,这种类型的设计模式属于行为型模式。
在策略模式中,我们可以创建各种表示策略的对象和一个策略行为,在程序运行时,通过不同的策略对象做出不同的行为策略。感觉就好像是多态一样,一个父类的引用指向子类的对象,不同的子类重写这个方法,当父类的引用指向不同的子类时,就会做出不同的行为。
主要用于解决:
-
在程序中有很多的相似的算法或者是程序段,使用策略模式可以减少代码冗余
-
使用策略模式是可以避免多条件选择的,因为不同的策略对象是有不同的具体实现的,如果,对象不同使用if...else...,那么程序的结构就会很复杂,很冗余,代码的耦合度也是很高的。
具体实现:
public interface Strategy { /** * 需要执行的具体的行为 */ void doTasking(); }
public class zhangsan implements Strategy{ /** * 具体的策略对象 */ @Override public void doTasking() { System.out.println("张三做事情"); } }
public class lisi implements Strategy{ /** * 具体的策略对象 */ @Override public void doTasking() { System.out.println("李四做事情"); } }
public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void executeStrategy() { strategy.doTasking(); } }
public class Main { public static void main(String[] args) { Context context1 = new Context(new zhangsan()); context1.executeStrategy(); Context context2 = new Context(new lisi()); context2.executeStrategy(); } } 结果: 张三做事情 李四做事情 Process finished with exit code 0
3、装饰器模式
装饰器模式,顾名思义,是用于装饰的东西的,也就是用来添加的。
装饰器模式允许向一个现有的对象添加新的功能,并且在不改变原有的结构的情况下,这种类型的设计模式是结构型模式,它是作为一个现有类的包装。
这种模式,它会去创建一个装饰类,用来包装现有的类,以实现添加新的内容。装饰器模式要比生成子类更加的灵活。
public interface Action { void eat(); }
/** * 接口的具体实现类 */ public class Cat implements Action{ @Override public void eat() { System.out.println("猫在吃饭"); } }
/** * 接口的具体实现类 */ public class Dog implements Action{ @Override public void eat() { System.out.println("狗在吃饭"); } }
public class Manin { public static void main(String[] args) { Action action1 = new Cat(); action1.eat(); Action action2 = new Dog(); action2.eat(); } } 结果: 猫在吃饭 狗在吃饭 Process finished with exit code 0
这是还没有被装饰。
下面看添加装饰
/** * 装饰抽象类,对现有的对象(接口),进行扩展 */ public abstract class ActionDecorator implements Action { // 现有接口 public Action action; public void eat() { action.eat(); } public ActionDecorator(Action action) { this.action = action; } }
/** * 对抽象类进行扩展,也就是开始真正的装饰了 */ public class IncreaseActionDecorator extends ActionDecorator{ public IncreaseActionDecorator(Action action) { super(action); } /** * 新增功能 */ public void run() { System.out.println("我要跑步"); } @Override public void eat() { action.eat(); run(); } }
public class Manin { public static void main(String[] args) { Action action1 = new Cat(); action1.eat(); Action action2 = new Dog(); action2.eat(); System.out.println("--------------------------------------"); Action action3 = new IncreaseActionDecorator(action1); action3.eat(); Action action4 = new IncreaseActionDecorator(action2); action4.eat(); } } 结果: 猫在吃饭 狗在吃饭 -------------------------------------- 猫在吃饭 我要跑步 狗在吃饭 我要跑步 Process finished with exit code 0