属于工厂模式,是一种弱化的工厂模式
public class OperationFactory{
public static Operation creatOperate(String operate){
Operation oper = null;
switch(operate){
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
}
return oper;
}
}
定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们能相互替换。
//定义计算接口
public interface CalculateStrategy{
int caluculatePrice(int km);
}
//公交车价格计算策略
public class BusStrategy implements CalculateStrategy{
/**
* 北京公交车,十公里之内一元钱,超过十公里每加一元钱,可以多乘5公里
*
* @param km
* @return
*/
@Override
public int caluculatePrice(int km) {
//超过10公里总距离
int extraTotal = km - 10;
//超过距离是5公里的倍数
int extraFactor = extraTotal / 5;
//超过5公里的地方对5公里取余
int faction = extraTotal % 5;
//价格计算
int price = 1 + extraFactor * 1;
return faction > 0 ? ++price : price;
}
}
/**
* 作者:${xiaojiukeji} on 17/5/21 16:55
* 作用: 地铁价格计算策略
*/
public class SubwayStrategy implements CalculateStrategy {
/**
* 6公里(含)3元, 6 ~~ 12公里(含)4元;
* 12 -- 22(含)公里,5元; 22 - 32 公里(含),6元
*
* @param km
* @return
*/
@Override
public int caluculatePrice(int km) {
if (km <= 6) {
return 3;
} else if (km > 6 && km <= 12) {
return 4;
} else if (km > 12 && km <= 22) {
return 5;
} else if (km > 22 && km <= 32) {
return 6;
}
//其他距离简化为7元
return 7;
}
}
public class TranficCalculator {
CalculateStrategy calculateStrategy;
public TranficCalculator(CalculateStrategy calculateStrategy) {
this.calculateStrategy = calculateStrategy;
}
//上下文接口
public void contextStrategy(int km) {
calculateStrategy.caluculatePrice(km);
}
}
//公交出行价格计算器
public class TrainficCalator {
public static void main(String[] args) {
TranficCalculator calculator = new TranficCalculator(new BusStrategy());//随意改变公交工具,对扩展开放,对修改关闭
calculator.contextStrategy(16);//公交16公里的价格
}
}
public abstract class Humburger {
protected String name ;
public String getName(){
return name;
}
public abstract double getPrice();
}
public class ChickenBurger extends Humburger {
public ChickenBurger() {
name = "鸡腿堡";
}
@Override
public double getPrice() {
return 10;
}
}
public abstract class Condiment extends Humburger {
public abstract String getName();
}
public class Lettuce extends Condiment {
Humburger humburger;
public Lettuce(Humburger humburger){
this.humburger = humburger;
}
@Override
public String getName() {
return humburger.getName()+" 加生菜";
}
@Override
public double getPrice() {
return humburger.getPrice()+1.5;
}
}
public class Chilli extends Condiment {
Humburger humburger;
public Chilli(Humburger humburger) {
this.humburger = humburger;
//new Lettuce(new ChickenBurger());
}
@Override
public String getName() {
return humburger.getName() + " 加辣椒";
}
@Override
public double getPrice() {
return humburger.getPrice(); //辣椒是免费的哦
}
}
public class Test {
public static void main(String[] args) {
Humburger humburger = new ChickenBurger();
System.out.println(humburger.getName() + " 价钱:" + humburger.getPrice());
Lettuce lettuce = new Lettuce(humburger);
System.out.println(lettuce.getName() + " 价钱:" + lettuce.getPrice());
Chilli chilli = new Chilli(humburger);
System.out.println(chilli.getName() + " 价钱:" + chilli.getPrice());
Chilli chilli2 = new Chilli(lettuce);
System.out.println(chilli2.getName() + " 价钱:" + chilli2.getPrice());
// 鸡腿堡 价钱:10.0
// 鸡腿堡 加生菜 价钱:11.5
// 鸡腿堡 加辣椒 价钱:10.0
// 鸡腿堡 加生菜 加辣椒 价钱:11.5
}
}
关键点:
定义:为其他对象提供一种代理以控制对这个对象的访问。
使用场景:当无法或者不想直接访问某一个对象时,可以通过一个代理对象来间接访问,为了委托客户端使用的透明性,委托对象与代理对象需要实现同一个接口。
public interface ILawsuit {
//提交申请
void submit();
//进行举证
void burden();
//开始辩护
void defend();
//诉讼完成
void finish();
}
public class XiaoMin implements ILawsuit {
@Override
public void submit() {
System.out.println("老板拖欠工资!因此申请仲裁!");
}
@Override
public void burden() {
System.out.println("这是合同书和过去一年银行的流水账单!");
}
@Override
public void defend() {
System.out.println("证据确凿,不用再多说了!");
}
@Override
public void finish() {
System.out.println("诉讼成功!马上发工资");
}
}
public class Lawyer implements ILawsuit {
private ILawsuit iLawsuit;
public Lawyer(ILawsuit iLawsuit) {
this.iLawsuit = iLawsuit;
}
@Override
public void submit() {
iLawsuit.submit();
}
@Override
public void burden() {
iLawsuit.burden();
}
@Override
public void defend() {
iLawsuit.defend();
}
@Override
public void finish() {
iLawsuit.finish();
}
}
public class Client {
public static void main(String[] args){
XiaoMin xiaoMin = new XiaoMin();
ILawsuit iLawsuit = new Lawyer(xiaoMin);
//律师开始替小民打官司
iLawsuit.submit();
iLawsuit.burden();
iLawsuit.defend();
iLawsuit.finish();
}
}
定义:定义一个用于创建对象的接口,让子类决定实例化哪个类。
使用场景:在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new 就可以完成的对象无需使用工厂模式。
优点:克服了简单工厂违背的开放-封闭原则的缺点,又保持了封装对象创建过程的优点。
缺点:每次为工厂方法添加新的产品的时候就要编写一个新的产品类。
在android中,onCreat()使用的即是该模式,还有java中的list和Set集合,都是这种模式
public abstract class Product {
/**
* 产品类的抽象方法,由具体的产品类去实现
*/
public abstract void method();
}
public class ConcreteProductA extends Product {
@Override
public void method() {
System.out.println("我是具体的产品A");
}
}
public class ConcreteProductB extends Product {
@Override
public void method() {
System.out.println("我是具体的产品B");
}
}
public abstract class Factory {
/**
* 抽象工厂方法,具体生产什么由子类去实现
*
* @param clz 产品对象类型
* @param 具体的产品对象
* @return
*/
public abstract <T extends Product> T createProduct(Class<T> clz);
}
public class ConcreteFactory extends Factory {
@Override
public <T extends Product> T createProduct(Class<T> clz) {
Product product = null;
try {
product = (Product) Class.forName(clz.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) product;
}
}
public class Client {
public static void main(String[] args) {
Factory factory = new ConcreteFactory();
Product product = factory.createProduct(ConcreteProductA.class);//需要什么就传什么
product.method();
}
}
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
注意: 只有当通过new 构造对象较为耗时间或者说成本比较高的时候,通过clone方法才能获得效率上的提升。
举例: 复制简历想要修改的问题
public class Prototype implements Cloneable {
private ArrayList list = new ArrayList();
public Prototype clone(){
Prototype prototype = null;
try{
prototype = (Prototype)super.clone();
prototype.list = (ArrayList) this.list.clone(); //引用类型的必须都要用深引用
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return prototype;
}
}
class ConcretePrototype extends Prototype{
public void show(){
System.out.println("原型模式实现类");
}
}
public class Client {
public static void main(String[] args){
ConcretePrototype cp = new ConcretePrototype();
for(int i=0; i< 10; i++){
ConcretePrototype clonecp = (ConcretePrototype)cp.clone();
clonecp.show();
}
}
}
定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法得某些特定步骤。
多个子类公有得方法,并且逻辑基本相同时。
重要、复杂的算法,可以把核心设计为模版方法,周边的相关细节功能则由各个子类实现。
重构时,模版方法模式是一个经常使用的模版,把相同的代码抽取到父类中,然后通过子函数约束其行为。
总结:就是封装流程。也就是把某个固定的流程封装到一个final函数中,并且让子类能够制定这个流程中的某些或所有步骤,
这就要求父类提取共用的代码,提升代码的复用率,同时也带来了很好的可扩展性。
优点:
1.封装不变的部分,变成可变部分
2.提取公告部分代码,便于维护。
缺点:
模版方法会带来代码阅读的难度,会让用户感觉难以理解。
public abstract class AbstractComputer {
protected void powerOn() {
System.out.println("开启电源");
}
protected void checkHardware() {
System.out.println("硬件检查");
}
protected void loadOs() {
System.out.println("载入操作系统");
}
protected void login() {
System.out.println("小白的计算机无需验证,直接登陆");
}
public final void startUp(){
System.out.println("----------------开机start--------------");
powerOn();
checkHardware();
loadOs();
login();
System.out.println("----------------关机End--------------");
}
}
public class CodeComputer extends AbstractComputer {
@Override
protected void login() {
// 注意:此处省略了super
// super.login();
System.out.print("程序员的电脑只需要用户和密码的验证就行");
}
}
public class MilitaryComputer extends AbstractComputer {
@Override
protected void checkHardware() {
super.checkHardware();
System.out.println("检查硬件防火墙");
}
@Override
protected void login() {
System.out.println("进行指纹识别等复杂的用户实验");
}
}
public class Test {
public static void main(String[] args){
AbstractComputer abstractComputer = new CodeComputer();
abstractComputer.startUp();
abstractComputer = new MilitaryComputer();
abstractComputer.startUp();
}
}
//输出结果如下:
// ----------开机start-----------
// 开启电源
// 硬件检查
// 载入操作系统
// 程序员的电脑只需要用户和密码的验证就行
// ----------------关机End--------------
// ----------开机start-----------
// 开启电源
// 硬件检查
// 检查硬件防火墙
// 载入操作系统
// 进行指纹识别等复杂的用户实验
// ----------------关机End--------------
将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
//计算机抽象类,即product角色
public abstract class Computer {
protected String mBoard;
protected String mDisplay;
protected String mOs;
public Computer() {
}
//设置CPU核心数
public void setmBoard(String mBoard) {
this.mBoard = mBoard;
}
//设置内存
public String getmDisplay() {
return mDisplay;
}
//设置操作系统
public void setmDisplay(String mDisplay) {
this.mDisplay = mDisplay;
}
public abstract void setmOs();
@Override
public String toString() {
return "Computer{" +
"mBoard='" + mBoard + '\'' +
", mDisplay='" + mDisplay + '\'' +
", mOs='" + mOs + '\'' +
'}';
}
}
//具体的Computer类
public class Macbook extends Computer {
public Macbook() {
}
@Override
public void setmOs() {
mOs = "Mac OS X 10.10";
}
}
//抽象类
public abstract class Builder {
//设置主机
public abstract void buildBoard(String board);
//设置显示器
public abstract void buildDisplay(String display);
//设置操作系统
public abstract void buildOS();
//创建Computer
public abstract Computer create();
}
//具体的builder类
public class MacbookBuilder extends Builder {
private Computer computer = new Macbook();
@Override
public void buildBoard(String board) {
computer.setmBoard(board);
}
@Override
public void buildDisplay(String display) {
computer.setmDisplay(display);
}
@Override
public void buildOS() {
computer.setmOs();
}
@Override
public Computer create() {
return computer;
}
}
//负责构造Computer,在实际使用中,常常被忽略掉
public class Director {
Builder builder = null;
public Director(Builder builder) {
this.builder = builder;
}
public void construct(String board,String display){
builder.buildBoard(board);
builder.buildDisplay(display);
builder.buildOS();
}
}
//测试类
public class Test {
public static void main(String[] args) {
Builder builder = new MacbookBuilder();
Director director = new Director(builder);
director.construct("inter的主板", "Retina显示器");
System.out.println("Computer Info : " + builder.create().toString());
}
}
public abstract class CarFactory {
/**
* 生产轮胎
* @return 轮胎
*/
public abstract ITire createTire();
/**
* 生产发动机
* @return 发动机
*/
public abstract IEngine createEngine();
/**
* 生产制动系统
* @return 制动系统
*/
public abstract IBreak createBreak();
}
public interface ITire {
/**
* 轮胎
*/
void tire();
}
public interface IEngine {
/**
* 发动机
*/
void engine();
}
public interface IBreak {
/**
* 制动
* */
void bradk();
}
public class NormalTire implements ITire {
@Override
public void tire() {
System.out.println("普通轮胎");
}
}
public class SuvTire implements ITire {
@Override
public void tire() {
System.out.println("SUV轮胎");
}
}
public class DomesticEngine implements IEngine {
@Override
public void engine() {
System.out.print("国产发动机");
}
}
public class ImportEngine implements IEngine {
@Override
public void engine() {
System.out.print("进口发动机");
}
}
public class NormalBrake implements IBreak {
@Override
public void bradk() {
System.out.print("普通制动");
}
}
public class SeniorBrake implements IBreak {
@Override
public void bradk() {
System.out.print("高级制动");
}
}
public class Q3Factory extends CarFactory {
@Override
public ITire createTire() {
return new NormalTire();
}
@Override
public IEngine vreateEngine() {
return new DomesticEngine();
}
@Override
public IBreak iBreak() {
return new NormalBrake();
}
}
public class Q7Factory extends CarFactory {
@Override
public ITire createTire() {
return new SuvTire();
}
@Override
public IEngine vreateEngine() {
return new ImportEngine();
}
@Override
public IBreak iBreak() {
return new SeniorBrake();
}
}
public class Client {
public static void main(String[] args) {
CarFactory factoryQ3 = new Q3Factory();
factoryQ3.createTire().tire();
factoryQ3.createEngine().engine();
factoryQ3.createBreak().bradk();
System.out.println("------------------");
CarFactory factoryQ7 = new Q7Factory();
factoryQ7.createTire().tire();
factoryQ7.createEngine().engine();
factoryQ7.createBreak().bradk();
}
}
定义:当一个对象的内在状态改变的时允许改变起行为,这个对象看起来像是改变了其类。
使用场景:
1. 一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。
2.代码中包含大量与对象状态有关的条件语句,例如,一个操作中含有庞大的多分支语句(if-else或switch-case),且这些分支依赖于该对象的状态。
优点:
通过多态的形式减少那些重复的判断语句,增强了可扩展性,灵活性。
缺点:
必然会增加系统类和对象的个数。
//电视状态
public interface TvState {
void nextChannel();
void prevChannel();
void tureUp();
void turnDown();
}
public class PowerOnState implements TvState {
@Override
public void nextChannel() {
System.out.println("下一频道");
}
@Override
public void prevChannel() {
System.out.println("上一频道");
}
@Override
public void tureUp() {
System.out.println("调高音量");
}
@Override
public void turnDown() {
System.out.println("调低音量");
}
}
//关机后的操作
public class PowerOffState implements TvState {
@Override
public void nextChannel() {
}
@Override
public void prevChannel() {
}
@Override
public void tureUp() {
}
@Override
public void turnDown() {
}
}
//设置两种状态
public interface PowerController {
void powerOn();
void powerOff();
}
//遥控器
public class TvController implements PowerController {
TvState mTvState;
public void setmTvState(TvState mTvState) {
this.mTvState = mTvState;
}
@Override
public void powerOn() {
setmTvState(new PowerOnState());
}
@Override
public void powerOff() {
setmTvState(new PowerOffState());
}
public void nextChannel(){
mTvState.nextChannel();
}
public void preChannel(){
mTvState.prevChannel();
}
public void turnUp(){
mTvState.tureUp();
}
}
public class Client {
public static void main(String[] args) {
TvController tvController = new TvController();
//设置开机状态
tvController.powerOn();
//下一频道
tvController.nextChannel();
//调高音量
tvController.turnUp();
//设置关机状态
tvController.powerOff();
//调高音量,此时不会生效
tvController.turnUp();
}
}
定义:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
使用场景:
1.关联行为场景,需要注意的是,关联行为是可拆分的,而不是“组合”关系;
2.事件多级触发场景;
3.跨系统的消息交换场景,如消息队列、事件总线的处理机制。
//程序员是观察者
public class Coder implements Observer {
public String name;
public Coder(String name) {
this.name = name;
}
@Override
public void update(Observable observable, Object data) {
System.out.println("Hi, " + name + "新内容来啦");
}
@Override
public String toString() {
return "码农 : " + name;
}
}
//被观察者,当它有更新的时候,所有的观察者(这里是Coder)都会接到相应的通知
public class NewContent extends Observable {
public void postNewPublication(String content){
//标示状态或者内容发生改变
setChanged();
//通知所有的观察者
notifyObservers(content);
}
}
public class Client {
public static void main(String[] args){
//被观察的对象
NewContent newContent = new NewContent();
//观察者
Coder coder = new Coder("mr.simple");
Coder coder1 = new Coder("coder-1");
Coder coder2 = new Coder("coder-2");
Coder coder3 = new Coder("coder-3");
//将观察者注册到可观察对象的观察列表中
newContent.addObserver(coder);
newContent.addObserver(coder1);
newContent.addObserver(coder2);
newContent.addObserver(coder3);
//发布消息
newContent.postNewPublication("新的一期开发技术周报发布啦!!!");
}
}
定义:适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
使用场景:
1.系统需要使用现在的类,而此类的接口不符合系统的需要,即接口不兼容。
2.想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
3.需要一个统一的输出接口,而输入端的类型不可预知。
//球员踢球
public abstract class Player {
protected String name;
public Player(String name) {
this.name = name;
}
public abstract void attack();
public abstract void defense();
}
//前锋
public class Forwards extends Player {
public Forwards(String name) {
super(name);
}
@Override
public void attack() {
System.out.println("前锋 进攻---->>>" + name);
}
@Override
public void defense() {
System.out.println("前锋 防守---->>>" + name);
}
}
//后卫
public class Center extends Player {
public Center(String name) {
super(name);
}
@Override
public void attack() {
System.out.println("后卫 进攻---->>>" + name);
}
@Override
public void defense() {
System.out.println("后卫 防守---->>>" + name);
}
}
//外籍中锋
public class ForeignCenter {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void 进攻() {
System.out.println("外籍中锋 进攻" + name);
}
public void 防守() {
System.out.println("外籍中锋 防守" + name);
}
}
//翻译者
public class Translator extends Player {
private ForeignCenter wjzf = new ForeignCenter();
public Translator(String name) {
super(name);
wjzf.setName(name);
}
@Override
public void attack() {
wjzf.进攻();
}
@Override
public void defense() {
wjzf.防守();
}
}
//客户端
public class Client {
public static void main(String[] args) {
Player b = new Forwards("巴蒂尔");
b.attack();
Player m = new Center("麦克");
m.attack();
Player ym = new Translator("姚明");
ym.attack();
ym.defense();
}
}
定义:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样,以后就可将该对象恢复到原先保存的状态。
应用场景:
1.需要保存一个对象在某一个时刻的状态或部分状态。
2.如果用一个接口来让其他对象得到这些状态,将会暴漏对象的实现细节并破坏对象的封装性,一个对象不希望外界直接访问其内部状态,通过中间对象可以间接访问其内部状态。
//备忘录类
public class Memoto {
public int mCheckPoint;
public int mLifeValue;
public String mWeapon;
@Override
public String toString() {
return "Memoto{" +
"mCheckPoint=" + mCheckPoint +
", mLifeValue=" + mLifeValue +
", mWeapon='" + mWeapon + '\'' +
'}';
}
}
//游戏
public class CallOfDuty {
private int mCheckPoint = 1;
private int mLifeValue = 100;
private String mWeapon = "沙漠之鹰";
//玩游戏
public void play() {
System.out.println("玩游戏 : " + String.format("第%d关", mCheckPoint) + "奋战杀敌中");
mLifeValue -= 10;
System.out.println("进度升级啦");
mCheckPoint++;
System.out.println("到达 : " + String.format("第%d关", mCheckPoint) + "奋战杀敌中");
}
//退出游戏
public void quit() {
System.out.println("-----------------");
System.out.println("退出前的游戏属性 : " + this.toString());
System.out.println("退出游戏");
System.out.println("-----------------");
}
//创建备忘录
public Memoto creatMemoto() {
Memoto memoto = new Memoto();
memoto.mCheckPoint = mCheckPoint;
memoto.mLifeValue = mLifeValue;
memoto.mWeapon = mWeapon;
return memoto;
}
//恢复游戏
public void restore(Memoto memoto) {
this.mCheckPoint = memoto.mCheckPoint;
this.mLifeValue = memoto.mLifeValue;
this.mWeapon = memoto.mWeapon;
System.out.println("回复后的游戏属性 : " + this.toString());
}
//TODO 省略了get 和 set 方法
@Override
public String toString() {
return "CallOfDuty{" +
"mCheckPoint=" + mCheckPoint +
", mLifeValue=" + mLifeValue +
", mWeapon='" + mWeapon + '\'' +
'}';
}
}
// 管理类
public class Caretaker {
Memoto memoto;
//存档
public void archive(Memoto memoto) {
this.memoto = memoto;
}
//获取存档
public Memoto getMemoto() {
return memoto;
}
}
public class Client {
public static void main(String[] args) {
//构建游戏对象
CallOfDuty game = new CallOfDuty();
//开始游戏
game.play();
Caretaker caretaker = new Caretaker();
//游戏存档
caretaker.archive(game.creatMemoto());
//退出游戏
game.quit();
//恢复游戏
CallOfDuty newGame = new CallOfDuty();
newGame.restore(caretaker.getMemoto());
}
}
定义: 将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象使用的一致性。
使用场景:
1.表示对象的部分-整体层次结构时。
2.从一个整体中能够独立出部分模块或功能的场景。
//公司类
public abstract class Company {
protected String name;
public Company(String name) {
this.name = name;
}
public abstract void add(Company c);//增加
public abstract void remove(Company c);//移除
}
//分级组合
public class ConcreteCompany extends Company {
private List<Company> children = new ArrayList<>();
public ConcreteCompany(String name) {
super(name);
}
@Override
public void add(Company c) {
children.add(c);
}
@Override
public void remove(Company c) {
children.remove(c);
}
}
//财务类
public class FinanceDepartment extends Company {
public FinanceDepartment(String name) {
super(name);
}
@Override
public void add(Company c) {
}
@Override
public void remove(Company c) {
}
}
//人事部
public class HRDepartment extends Company {
public HRDepartment(String name) {
super(name);
}
@Override
public void add(Company c) {
}
@Override
public void remove(Company c) {
}
}
//客户端
public class Client {
public static void main(String[] args) {
ConcreteCompany root = new ConcreteCompany("北京总公司");
root.add(new HRDepartment("总公司人力资源部"));
root.add(new FinanceDepartment("总公司财务部"));
ConcreteCompany comp = new ConcreteCompany("上海分公司");
comp.add(new HRDepartment("上海分公司人力资源部"));
comp.add(new FinanceDepartment("上海分公司财务部"));
root.add(comp);
ConcreteCompany comp1 = new ConcreteCompany("南京办事处");
comp1.add(new HRDepartment("南京办事处人力资源部"));
comp1.add(new FinanceDepartment("南京办事处财务部"));
comp.add(comp1);
}
}
定义:提供一种方法顺序访问一个容器对象中的各个元素,而又不需要暴漏该对象的内部显示。
使用场景:
遍历一个容器对象时。
public interface Iterator {
//是否还有下一个元素 true 表示有,false 表示没有
boolean hasNext();
//返回当前位置的元素,并将位置移至下一位
Object next();
}
//查询信息的类
public class Employee {
private String name;
private int age;
private String sex;
private String position;
public Employee(String name, int age, String sex, String position) {
this.name = name;
this.age = age;
this.sex = sex;
this.position = position;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", position='" + position + '\'' +
'}';
}
}
public class MinIterator implements Iterator {
private List<Employee> list;
private int position;
public MinIterator(List<Employee> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return !(position > list.size() - 1 || list.get(position) == null);
}
@Override
public Object next() {
Employee employee = list.get(position);
position++;
return employee;
}
}
//和MinIterator 是两种不同的查询方式
public class HuiIterator implements Iterator {
private Employee[] array;
private int position;
public HuiIterator(Employee[] array) {
this.array = array;
}
@Override
public boolean hasNext() {
return !(position > array.length - 1 || array[position] == null);
}
@Override
public Object next() {
Employee employee = array[position];
position++;
return employee;
}
}
public interface Company {
//返回一个迭代器对象
Iterator iterator();
}
public class CompanyHui implements Company {
private Employee[] array = new Employee[3];
public CompanyHui() {
array[0] = new Employee("辉哥", 108, "男", "程序员");
array[1] = new Employee("小红", 98, "男", "程序员");
array[2] = new Employee("小晴", 102, "男", "程序员");
}
@Override
public Iterator iterator() {
return new HuiIterator(array);
}
public Employee[] getEmployees() {
return array;
}
}
public class CompanyMIn implements Company {
private List<Employee> list = new ArrayList<>();
public CompanyMIn() {
list.add(new Employee("小民", 92, "男", "程序员"));
list.add(new Employee("小芳", 22, "女", "测试"));
list.add(new Employee("小可", 23, "女", "测试"));
list.add(new Employee("小朗", 20, "男", "设计"));
}
public List<Employee> getEmployees() {
return list;
}
@Override
public Iterator iterator() {
return new MinIterator(list);
}
}
//当Boss查询的时候,就只需查询就可
public class Boss {
public static void main(String[] args) {
CompanyMIn companyMIn = new CompanyMIn();
check(companyMIn.iterator());
CompanyHui companyHui = new CompanyHui();
check(companyHui.iterator());
}
private static void check(Iterator iterator) {
while (iterator.hasNext()) {
System.out.println(iterator.next().toString());
}
}
}
//懒汉模式是声明一个静态对象,并且在用户第一次调用getInstance时进行初始化
public class Signleton {
private static Signleton instance;
private Signleton() {
}
//进行同步,造成不必要的同步开销。不推荐这种方法。
public static synchronized Signleton getInstance() {
if (instance == null) {
instance = new Signleton();
}
return instance;
}
}
public class Signleton {
private static Signleton instance = null;
private Signleton() {
}
/**
* 优点:既能够在需要时才初始化单例,又能保证线程安全
* 缺点:由于java内存模型的原因(乱序执行)偶尔会失败
*/
public static Signleton getInstance() {
if (instance == null) {//避免不必要的同步
synchronized (Signleton.class){
if (instance == null){//在instance为null的情况下创建实例
instance = new Signleton();
}
}
}
return instance;
}
}
--由于jvm的特性,允许乱序执行,所以上面的DCL的执行顺序不定,就有可能出现DCL失效的问题。
为了解决这一问题,java1.6开始加入volatile关键字
private volatile static Signleton instance.
这种情况就避免了DCL方法失效,但是volatile消耗一些性能
//推荐使用方法 ,静态内部类方式,确保线程安全,保证单例唯一
//第一次加载的时候并不会初始化sInstance,只有在第一次调用Singleton的getInstance方法时才会导致初始化。
public class Signleton {
private Signleton() {
}
public static Signleton getInstance() {
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Signleton sInstance = new Signleton();
}
}
定义:将抽象部分与实现部分分离,使它们都可以独立的进行变化。
使用场景:
一个类存在两个独立变化的纬度,且这两个纬度都需要进行扩展。
public abstract class CoffeeAdditivies {
/**
* 具体要往咖啡里添加什么也是由子类实现
* @return 具体添加的东西
*/
public abstract String addSomething();
}
public class Ordinary extends CoffeeAdditivies {
@Override
public String addSomething() {
return "原味";
}
}
public class Sugar extends CoffeeAdditivies {
@Override
public String addSomething() {
return "加糖";
}
}
public abstract class Coffee {
protected CoffeeAdditivies impl;
public Coffee(CoffeeAdditivies impl) {
this.impl = impl;
}
/**
* 咖啡具体是什么样的由子类决定
*/
public abstract void makeCoffee();
}
public class LarrgeCoffee extends Coffee {
public LarrgeCoffee(CoffeeAdditivies impl) {
super(impl);
}
@Override
public void makeCoffee() {
System.out.println("大杯的" + impl + "咖啡");
}
}
public class SmallCoffee extends Coffee {
public SmallCoffee(CoffeeAdditivies impl) {
super(impl);
}
@Override
public void makeCoffee() {
System.out.println("小杯的 " + impl + "咖啡");
}
}
public class Client {
public static void main(String[] args) {
//原汁原味
Ordinary impOrdinary = new Ordinary();
//准备加糖
Sugar implSugar = new Sugar();
//大杯咖啡 原味
LarrgeCoffee larrgeCoffee = new LarrgeCoffee(impOrdinary);
larrgeCoffee.makeCoffee();
//小杯咖啡 加糖
SmallCoffee smallCoffee = new SmallCoffee(implSugar);
smallCoffee.makeCoffee();
}
}
定义:讲一个请求封装成一个对象,从而让用户使用不同的请求把客户端参数化;对请求拍队或者记录请求日志,以及支持可撤销的操作。
使用场景:
1. 需要支持取消操作。
2. 支持修改日志功能,这样当系统崩溃时,这些修改可以重做一遍。
3. 需要支持事物操作。
//接受者角色
public class TetrisMachine {
public void toLeft(){
System.out.println("向左");
}
public void toRight(){
System.out.println("向右");
}
}
//命令者抽象 定义执行方法
public interface Command {
void execute();
}
public class LeftCommand implements Command {
private TetrisMachine tetrisMachine;
public LeftCommand(TetrisMachine tetrisMachine) {
this.tetrisMachine = tetrisMachine;
}
@Override
public void execute() {
tetrisMachine.toLeft();
}
}
public class RightCommand implements Command {
private TetrisMachine tetrisMachine;
public RightCommand(TetrisMachine tetrisMachine) {
this.tetrisMachine = tetrisMachine;
}
@Override
public void execute() {
tetrisMachine.toRight();
}
}
public class Button {
private LeftCommand leftCommand;
private RightCommand rightCommand;
public void setLeftCommand(LeftCommand leftCommand) {
this.leftCommand = leftCommand;
}
public void setRightCommand(RightCommand rightCommand) {
this.rightCommand = rightCommand;
}
public void toLeft() {
leftCommand.execute();
}
public void toRight() {
rightCommand.execute();
}
}
public class Client {
public static void main(String[] args) {
TetrisMachine tetrisMachine = new TetrisMachine();
//根据游戏我们构造4种命令
LeftCommand leftCommand = new LeftCommand(tetrisMachine);
RightCommand rightCommand = new RightCommand(tetrisMachine);
//按钮可以执行不同的命令
Button button = new Button();
button.setLeftCommand(leftCommand);
button.setRightCommand(rightCommand);
//具体按下哪个,玩家说了算
button.toLeft();
button.toRight();
}
}
可以直接实现:
public class Client {
public static void main(String[] args) {
TetrisMachine tetrisMachine = new TetrisMachine();
tetrisMachine.toLeft();
tetrisMachine.toRight();
}
}
定义:使多个对象都有机会处理请求,从而避免来请求的发送者和接收者之间的耦合关系。将这些对象连城一条链,并沿着这条链传递该请求,只到有对象处理它为止。
使用场景:
1. 多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
2. 在请求处理者不明确的情况下向多个对象中的一个提交一个请求。
3. 需要动态指定一组对象处理请求。
public abstract class Leader {
protected Leader nextHandler;//上一级领导处理者
/*
* 处理报账请求
* */
public final void handleRequest(int money) {
if (money < limit()) {
handle(money);
} else {
if (null != nextHandler) {
nextHandler.handleRequest(money);
}
}
}
/**
* 自身能批复的额度权限
*/
public abstract int limit();
/**
* 处理报账行为
*/
public abstract void handle(int money);
}
public class GroupLeader extends Leader {
@Override
public int limit() {
return 1000;
}
@Override
public void handle(int money) {
System.out.println("组长批复报销" + money + "元");
}
}
public class Director extends Leader {
@Override
public int limit() {
return 5000;
}
@Override
public void handle(int money) {
System.out.println("主管批复报销" + money + "元");
}
}
public class Boss extends Leader {
@Override
public int limit() {
return Integer.MAX_VALUE;
}
@Override
public void handle(int money) {
System.out.println("老板批复报销" + money + "元");
}
}
public class Client {
public static void main(String[] args) {
GroupLeader groupLeader = new GroupLeader();
Director director = new Director();
Boss boss = new Boss();
//设置上一级领导处理者对象
groupLeader.nextHandler = director;
director.nextHandler = boss;
//发起账单申请
groupLeader.handleRequest(20000);
}
}
定义: 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
使用场景:
1.当对象之间的交互操作很多且每个对象的行为操作都依赖彼此时,为防止在修改一对象的行为时,同时设计修改很多其他对象的行为,可采用中介者模式。
// 抽象同事类
public class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
}
public class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator mediator) {
super(mediator);
}
public void send(String message) {
mediator.send(message, this);
}
public void notify(String message) {
System.out.println("同事1得到消息:" + message);
}
}
public class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator mediator) {
super(mediator);
}
public void send(String message) {
mediator.send(message, this);
}
public void notify(String message) {
System.out.println("同事2得到消息: " + message);
}
}
// 抽象中介者
public abstract class Mediator {
/**
* 同事对象改变时通知中介者方法
* 在同事对象改变时由中介者去通知其他的同事对象
*/
public abstract void send(String message,Colleague collegue);
}
// 具体的中介者类
public class ConcreteMediator extends Mediator {
private ConcreteColleague1 concreteColleague1;
private ConcreteColleague2 concreteColleague2;
public void setConcreteColleague1(ConcreteColleague1 concreteColleague1) {
this.concreteColleague1 = concreteColleague1;
}
public void setConcreteColleague2(ConcreteColleague2 concreteColleague2) {
this.concreteColleague2 = concreteColleague2;
}
@Override
public void send(String message, Colleague collegue) {
if (collegue == concreteColleague1) {
concreteColleague2.notify();
} else {
concreteColleague1.notify();
}
}
}
public class Client {
public static void main(String[] args) {
ConcreteMediator concreteMediator = new ConcreteMediator();
ConcreteColleague1 concreteColleague1 = new ConcreteColleague1(concreteMediator);
ConcreteColleague2 concreteColleague2 = new ConcreteColleague2(concreteMediator);
concreteMediator.setConcreteColleague1(concreteColleague1);
concreteMediator.setConcreteColleague2(concreteColleague2);
concreteColleague1.send("吃过饭没有");
concreteColleague2.send("没有呢,你打算请客吗?");
}
}
定义:当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象的语法树时,可使用解释器模式。
//解释器共性的提取
public abstract class ArithmeticExpression {
//抽象的解析方法,具体的解析逻辑由具体的子类的实现
public abstract int interpret();
}
public class NumExpression extends ArithmeticExpression {
private int num;
public NumExpression(int num) {
this.num = num;
}
@Override
public int interpret() {
return num;
}
}
public class OperatorExpression extends ArithmeticExpression {
protected ArithmeticExpression expression1,expression2;
public OperatorExpression(ArithmeticExpression expression1, ArithmeticExpression expression2) {
this.expression1 = expression1;
this.expression2 = expression2;
}
@Override
public int interpret() {
return 0;
}
}
public class AdditionExpression extends OperatorExpression {
public AdditionExpression(ArithmeticExpression expression1, ArithmeticExpression expression2) {
super(expression1, expression2);
}
@Override
public int interpret() {
return expression1.interpret() + expression2.interpret();
}
}
//处理和解释相关的一些业务
public class Calculator {
private Stack<ArithmeticExpression> mExpStack = new Stack<ArithmeticExpression>();
public Calculator(String expression) {
ArithmeticExpression expression1, expression2;
String[] elements = expression.split(" ");
for (int i = 0; i < elements.length; i++) {
switch (elements[i].charAt(0)) {
case '+':
//则将栈中的解释器弹出作为运算符号左边的解释器
expression1 = mExpStack.pop();
//同时将运算符号数组下标一个下一个元素构成为一个数字解释器
expression2 = new NumExpression(Integer.valueOf(elements[++i]));
//通过上面两个数字解释器构造加法运算解释器
mExpStack.push(new AdditionExpression(expression1, expression2));
break;
default://如果为数字
mExpStack.push(new NumExpression(Integer.valueOf(elements[i])));
break;
}
}
}
public int calculate() {
return mExpStack.pop().interpret();
}
}
public class Client {
public static void main(String[] args) {
Calculator calculator = new Calculator("153 + 3589 + 118 + 555");
System.out.println(calculator.calculate());
}
}
定义:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
使用场景:
1.对象结构比较稳定,但经常需要在此对象结构上定义新的操作。
2.需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。
public interface Visitor {
//访问工程师类型
public void visit(Engineer engineer);
//访问经理类型
public void visit(Manager leader);
}
public class CEOVisitor implements Visitor {
@Override
public void visit(Engineer engineer) {
System.out.println("工程师 : " + engineer.name + ",KPI : " + engineer.kpi);
}
@Override
public void visit(Manager leader) {
System.out.println("工程师 : " + leader.name + ",KPI : " + leader.kpi + ",新产品数量 : " + leader.getProducts());
}
}
public class CTOVisitor implements Visitor {
@Override
public void visit(Engineer engineer) {
System.out.println("工程师 : " + engineer.name + "代码函数 : " + engineer.getCodeLines());
}
@Override
public void visit(Manager leader) {
System.out.println("经理 : " + leader.name + "产品数量 : " + leader.getProducts());
}
}
public abstract class Staff {
public String name;
public int kpi;
public Staff(String name) {
this.name = name;
}
public abstract void accept(Visitor visitor);
}
public class Engineer extends Staff {
public Engineer(String name) {
super(name);
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
// 工程师一年写的代码量
public int getCodeLines() {
return new Random().nextInt(10 * 10000);
}
}
public class Manager extends Staff{
private int products;
public Manager(String name) {
super(name);
products = new Random().nextInt(10);
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
//一年内做的产品数量
public int getProducts(){
return products;
}
}
public class BusinessReport {
List<Staff> mStaffs = new LinkedList<>();
public BusinessReport() {
mStaffs.add(new Manager("王经理"));
mStaffs.add(new Engineer("工程师-小王"));
mStaffs.add(new Engineer("工程师-小李"));
mStaffs.add(new Engineer("工程师-小张"));
}
public void showReport(Visitor visitor){
for (Staff staff : mStaffs){
staff.accept(visitor);
}
}
}
public class Client {
public static void main(String[] args) {
BusinessReport report = new BusinessReport();
System.out.println("=========== 给CEO看的报表 ===========");
//设置访问者,这里是CEO
report.showReport(new CEOVisitor());
System.out.println("=========== 给CTO看的报表 ===========");
//注入另一个访问者,CTO
report.showReport(new CTOVisitor());
}
}
public class ReportUitl {
public void visit(Staff staff){
if (staff instanceof Manager ){
Manager manager = (Manager) staff;
System.out.println("经理 : "+ manager.name + ",KPI : "+ manager.kpi + ",新产品数量 : "+manager.getProducts());
}else {
Engineer engineer = (Engineer) staff;
System.out.println("工程师 : "+ engineer.name + ",KPI : "+ engineer.kpi );
}
}
}