常见的设计模式(模板、策略、装饰器)
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
查看2道真题和解析