模板方法模式
提供一个抽象类,将部分逻辑以具体方法或构造器的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法(多态实现),从而实现不同的业务逻辑。
使用场景
1)多个子类有公有的方法,并且逻辑基本相同时
2)重要、复杂的算法,可以把核心算法设计为模板方法
3)重构时,模板方法模式是一个经常使用的模式
public abstract class AbstractWork {
protected void getUp() {
System.out.println("起床啦!");
}
protected abstract void goToWork();
protected abstract void work();
protected abstract void getOffWork();
/*
* TemplateMethod,大家都拥有共同的执行步骤
*/
public final void newDay() {
getUp();
goToWork();
work();
getOffWork();
}
}
public class BossWork extends AbstractWork {
@Override
protected void goToWork() {
System.out.println("老板开车去上班");
}
@Override
protected void work() {
System.out.println("老板的分配工作给员工");
}
@Override
protected void getOffWork() {
System.out.println("老板开车去下班");
}
}
public class StaffWork extends AbstractWork {
@Override
protected void goToWork() {
System.out.println("员工做公交去上班");
}
@Override
protected void work() {
System.out.println("员工处理具体工作");
}
@Override
protected void getOffWork() {
System.out.println("员工做公交下班");
}
}
public class Test {
public static void main(String[] args) {
BossWork bossWork = new BossWork();
StaffWork staffWork = new StaffWork();
bossWork.newDay();
System.out.println("------------------------");
staffWork.newDay();
}
}
策略模式
定义了算法家庭,分别封装起来。让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
一个类定义了多种行为,并且这些行为在这个类的方法中以多个条件语句的形式出现,那么可以使用策略模式避免在类中使用大量的条件语句。
public interface AbstractStrategy {
//按距离来计算价格
int calculatePrice(int km);
}
public class BusStrategy implements AbstractStrategy {
@Override
public int calculatePrice(int km) {
int extraTotal = km - 10;
int extraFactor = extraTotal / 5;
int fraction = extraTotal % 5;
int price = 1 + extraTotal % 5;
return fraction > 0 ? ++price : price;
}
}
public class TaxiStrategy implements AbstractStrategy {
@Override
public int calculatePrice(int km) {
return km * 2;
}
}
public class Context {
private AbstractStrategy strategy;
public void setStrategy(AbstractStrategy strategy) {
this.strategy = strategy;
}
public int calclatePrice(int km) {
return strategy.calculatePrice(km);
}
public static void main(String[] strings) {
Context calculator = new Context();
calculator.setStrategy(new BusStrategy());
// calculator.setStrategy(new TaxiStrategy());
System.out.println("公交车20km价格:" + calculator.calclatePrice(20));
}
}
传统写法
//PriceCalculator 类很明显的问题就是并不是单一职责,首先它承担计算公交车和地铁乘坐价格的职责,
//另一个问题就是通过if-else的形式来判断使用哪种计算形式。当我们增加一种出行方式时,如出租车,
//那么我们就需要在PriceCalculator 中增加一个方法来计算出租车出行的价格,并且在calculatePrice(int km, int type)函数增加一个判断
public static class PriceCalculator {
private static final int TAXI = 3;
private static final int BUS = 1;
private static final int SUBWAY = 2;
public static void main(String[] strings) {
PriceCalculator calculator = new PriceCalculator();
System.out.println("做20km公交票价:" + calculator.calculatePrice(20, BUS));
System.out.println("做20km地铁票价:" + calculator.calculatePrice(20, SUBWAY));
}
private int busPrice(int km) {
return km * 1;
}
public int taxiPrice(int km) {
return km * 7;
}
/**
* 根据不同类型计算
*/
int calculatePrice(int km, int type) {
if (type == BUS) {
return busPrice(km);
} else if (type == SUBWAY) {
return taxiPrice(km);
}
return 0;
}
}
组合模式
使用户对单个对象和组合对象的使用具有一致性。将对象组合成树形结构以表示“部分-整体”的层次结构。
Component : 组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。
Leaf : 表示叶节点对象。叶子节点没有子节点。
Composite : 定义枝节点行为,用来存储子部件,在 Component 接口中实现与子部件相关的操作。例如 Add 和 Remove
public abstract class File {
private String name;
public File(String name) {
this.name = name;
}
//操作方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void watch();
//组合方法
public void add(File file) {
throw new UnsupportedOperationException();
}
public void remove(File file) {
throw new UnsupportedOperationException();
}
public File getChild(int position) {
throw new UnsupportedOperationException();
}
}
public class Folder extends File {
private List<File> mFileList;
public Folder(String name) {
super(name);
mFileList = new ArrayList<>();
}
@Override
public void watch() {
StringBuffer fileName = new StringBuffer();
for (File file : mFileList) {
fileName.append(file.getName() + ";");
}
System.out.println("组合模式:这是一个叫" + getName() + "文件夹,包含" + mFileList.size() + "个文件,分别是:" + fileName);
}
@Override
public void add(File file) {
mFileList.add(file);
}
@Override
public void remove(File file) {
mFileList.remove(file);
}
@Override
public File getChild(int position) {
return mFileList.get(position);
}
}
public class TextFile extends File {
public TextFile(String name) {
super(name);
}
@Override
public void watch() {
System.out.println("组合模式:这是一个叫" + getName() + "文本文件");
}
}
public class testComposite {
public static void main(String[] strings) {
TextFile textFileA = new TextFile("a.txt");
TextFile textFileB = new TextFile("b.txt");
TextFile textFileC = new TextFile("c.txt");
textFileA.watch();
// textFileA.add(textFileB);//调用会抛我们在抽象接口中写的异常
Folder folder = new Folder("学习资料");
folder.add(textFileA);
folder.add(textFileB);
folder.add(textFileC);
folder.watch();
folder.getChild(1).watch();
Folder folder1 = new Folder("个人资料");
folder1.add(textFileA);
folder1.add(textFileB);
//可以随便组合
Folder folder2 = new Folder("D盘资料");
folder2.add(folder);
folder2.add(folder1);
}
}
观察者模式
定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆可得到通知并被自动更新。
观察者模式在android中的实际运用:回调模式
回调模式:实现了抽象类/接口的实例实现了父类的提供的抽象方法
后,将该方法交还给父类来处理。
例如:
通过 setOnClickListener() 方法,Button 持有 OnClickListener 的引用(这一过程没有在图上画出);当用户点击时,Button 自动调用 OnClickListener 的 onClick() 方法。另外,如果把这张图中的概念抽象出来(Button(view) -> 被观察者、OnClickListener -> 观察者、setOnClickListener() -> 订阅,onClick() -> 事件),就由专用的观察者模式(例如只用于监听控件点击)转变成了通用的观察者模式。
public class ObserverPattern {
public interface Observer {
void update(String state);
}
public class ConcreteObserver implements Observer {
// 观察者状态
private String observerState;
@Override
public void update(String state) {
// 更新观察者状态,让它与目标状态一致
observerState = state;
System.out.println("ConcreteObserver State :" + observerState);
}
}
/**
* 抽象订阅者(目标者)
* 被观察者
*
*/
public abstract class Subject {
// 保存注册的观察者对象
private List<Observer> mObservers = new ArrayList<>();
//注册观察者对象
public void attach(Observer observer) {
mObservers.add(observer);
System.out.println("Attached an observer");
}
//注销观察者对象
public void detach(Observer observer) {
mObservers.remove(observer);
}
// 通知所有注册的观察者对象
public void nodifyObservers(String newState) {
for (Observer observer : mObservers) {
observer.update(newState);
}
}
}
public class ConcreteSubject extends Subject {
private String state;
public String getState() {
return state;
}
public void change(String newState) {
state = newState;
System.out.println("ConcreteSubject State:" + state);
//状态发生改变,通知观察者
nodifyObservers(state);
}
}
public static void main(String[] args) {
ObserverPattern observerPattern = new ObserverPattern();
ConcreteSubject concreteSubject = observerPattern.new ConcreteSubject();
Observer observer1 = observerPattern.new ConcreteObserver();
Observer observer2 = observerPattern.new ConcreteObserver();
// 将观察者对象注册到目标对象上
concreteSubject.attach(observer1);
concreteSubject.attach(observer2);
// 改变目标对象的状态
concreteSubject.change("I change");
}
}
相关源码:
https://github.com/peiniwan/DesignPattern.git