一简单工厂模式代码无错就是优二策略模式出行公交打车android中的动画三装饰模式 -android源码中Context和ContextIml四 代理模式为别人做嫁衣五 工厂模式六 原型模式 Intent 等七 模版模式八 Builder模式九抽象工厂模式十状态模式电视遥控器开关Wi-Fi等等十一观察者模式十二适配器模式姚明去NBA打篮球需要翻译十三备忘录模式十四 组合模式View 和ViewGroup公司故事十五迭代器模式十六单例模式
懒汉模式Double Check Lock DCL 实现单例 十七 桥接模式十八 命令模式 几乎体现了设计模式的所有的通病就是类的膨胀
敏捷开发原则告诉我们不要为代码添加基于猜测的实际不需要的功能如果不清楚一个系统是否需要命令模式一般就不要着急去实现它 十九 责任链模式二十 中介者模式二十一解释器模式二十二访问者模式
一:简单工厂模式:代码无错就是优?
属于工厂模式,是一种弱化的工厂模式
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;
}
}
二:策略模式:出行(公交,打车。。。)(android中的动画)
定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们能相互替换。
- 计算规则接口
public interface CalculateStrategy{
int caluculatePrice(
int km);
}
公交计算价格策略
public class BusStrategy implements CalculateStrategy{
/**
* 北京公交车,十公里之内一元钱,超过十公里每加一元钱,可以多乘5公里
*
* @param km
* @return
*/
@Override
public int caluculatePrice(
int km) {
int extraTotal = km -
10;
int extraFactor = extraTotal /
5;
int faction = extraTotal %
5;
int price =
1 + extraFactor *
1;
return faction >
0 ? ++price : price;
}
}
地铁价格计算 “` java /**作者:${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; } }
- 定义一个扮演着Context角色的类
``` java
public class TranficCalculator {
CalculateStrategy calculateStrategy;
public TranficCalculator(CalculateStrategy calculateStrategy) {
this.calculateStrategy = calculateStrategy;
}
public void contextStrategy(
int km) {
calculateStrategy.caluculatePrice(km);
}
}
<div class=
"se-preview-section-delimiter"></div>
执行类
public class TrainficCalator {
public static void main(String[] args) {
TranficCalculator calculator =
new TranficCalculator(
new BusStrategy());
calculator.contextStrategy(
16);
}
}
<div class=
"se-preview-section-delimiter"></div>
三:装饰模式 —->>>android源码中:Context和ContextIml
汉堡基类(被装饰者)
public abstract class Humburger {
protected String name ;
public String
getName(){
return name;
}
public abstract double getPrice();
}
<div class=
"se-preview-section-delimiter"></div>
鸡腿堡类(被装饰者的初始状态,有些自己的简单装饰)
public class ChickenBurger extends Humburger {
public ChickenBurger() {
name =
"鸡腿堡";
}
@Override
public double getPrice() {
return 10;
}
}
<div class=
"se-preview-section-delimiter"></div>
配料的基类(装饰者,用来对汉堡进行多层装饰,每层装饰增加一些配料)
public abstract class Condiment extends Humburger {
public abstract String
getName();
}
<div class=
"se-preview-section-delimiter"></div>
生菜(装饰者的第一层)
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;
}
}
<div class=
"se-preview-section-delimiter"></div>
辣椒(装饰者的第二层)
public class Chilli extends Condiment {
Humburger humburger;
public Chilli(Humburger humburger) {
this.humburger = humburger;
}
@Override
public String
getName() {
return humburger.getName() +
" 加辣椒";
}
@Override
public double getPrice() {
return humburger.getPrice();
}
}
<div class=
"se-preview-section-delimiter"></div>
测试类,测试被装饰的结果
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());
}
}
<div class=
"se-preview-section-delimiter"></div>
关键点: 1. Condiment抽象类中,持有Humburger接口,方法全部委托给该接口调用,目的是交给该接口的实现类即子类进行调用。 2. Condiment抽象类的子类(具体装饰者),里面都有一个构造方法调用super(Humburger),这一句就体现了抽象类依赖于子类实现即抽象依赖于实现的原则。因为构造里面参数都是humburger接口,只要是该Humburger的实现类都可以传递进去,即表现出Condiment cd = new Chilli(new Lettuce(new ChickenBurger()));这种结构的样子。,而该super已经由构造传递并指向了具体的某一个装饰者类(这个可以根据需要调换顺序),那么调用的即为装饰类的方法,然后才调用自身的装饰方法,即表现出一种装饰、链式的类似于过滤的行为。 3. 具体被装饰者类,可以定义初始的状态或者初始的自己的装饰,后面的装饰行为都在此基础上一步一步进行点缀、装饰。 4. 装饰者模式的设计原则为:对扩展开放、对修改关闭,这句话体现在我如果想扩展被装饰者类的行为,无须修改装饰者抽象类,只需继承装饰者抽象类,实现额外的一些装饰或者叫行为即可对被装饰者进行包装。所以:扩展体现在继承、修改体现在子类中,而不是具体的抽象类,这充分体现了依赖倒置原则,这是自己理解的装饰者模式。
四. 代理模式----(为别人做嫁衣)
定义:为其他对象提供一种代理以控制对这个对象的访问。
使用场景:当无法或者不想直接访问某一个对象时,可以通过一个代理对象来间接访问,为了委托客户端使用的透明性,委托对象与代理对象需要实现同一个接口。
- 例:小民委托律师要回自己的工资 - 接口类
public interface ILawsuit {
void submit();
void burden();
void defend();
void finish();
}
<div class=
"se-preview-section-delimiter"></div>
委托人
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(
"诉讼成功!马上发工资");
}
}
<div class=
"se-preview-section-delimiter"></div>
代理律师
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();
}
}
<div class=
"se-preview-section-delimiter"></div>
开庭审理的客户类
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();
}
}
<div class=
"se-preview-section-delimiter"></div>
五. 工厂模式:
定义:定义一个用于创建对象的接口,让子类决定实例化哪个类。
使用场景:在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new 就可以完成的对象无需使用工厂模式。
优点:克服了简单工厂违背的开放-封闭原则的缺点,又保持了封装对象创建过程的优点。
缺点:每次为工厂方法添加新的产品的时候就要编写一个新的产品类。
在android中,onCreat()使用的即是该模式,还有java中的list和Set集合,都是这种模式
定义一个抽象产品类
public abstract class Product {
/**
* 产品类的抽象方法,由具体的产品类去实现
*/
public abstract void method();
}
<div class=
"se-preview-section-delimiter"></div>
具体的产品实现类
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");
}
}
<div class=
"se-preview-section-delimiter"></div>
抽象工厂类
public abstract class Factory {
/**
* 抽象工厂方法,具体生产什么由子类去实现
*
* @param clz 产品对象类型
* @param <T> 具体的产品对象
* @return
*/
public abstract <T extends Product> T
createProduct(Class<T> clz);
}
<div class=
"se-preview-section-delimiter"></div>
具体的工厂类,通过反射获取类的事例即可
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;
}
}
<div class=
"se-preview-section-delimiter"></div>
客户端中具体的实现
public class Client {
public static void main(String[] args) {
Factory factory =
new ConcreteFactory();
Product product = factory.createProduct(ConcreteProductA.class);
product.method();
}
}
<div class=
"se-preview-section-delimiter"></div>
六. 原型模式 (Intent 等)
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
实现CLoneable接口。作用是在运行时通知虚拟机可以安全的实现了此接口的类上使用clone方法。重写Object类中的clone方法。Java中,所有类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此,Prototype类需要将clone方法的作用域修改为public类型
注意: 只有当通过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;
}
}
<div class=
"se-preview-section-delimiter"></div>
原型实现类
class ConcretePrototype extends Prototype{
public void show(){
System.out.println(
"原型模式实现类");
}
}
<div class=
"se-preview-section-delimiter"></div>
客户端执行
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();
}
}
}
<div class=
"se-preview-section-delimiter"></div>
七. 模版模式:
定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法得某些特定步骤。
- 使用场景 1. 多个子类公有得方法,并且逻辑基本相同时。 2. 重要、复杂的算法,可以把核心设计为模版方法,周边的相关细节功能则由各个子类实现。 3. 重构时,模版方法模式是一个经常使用的模版,把相同的代码抽取到父类中,然后通过子函数约束其行为。
总结:就是封装流程。也就是把某个固定的流程封装到一个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--------------");
}
}
<div class=
"se-preview-section-delimiter"></div>
具体流程改变(程序员电脑类)
public class CodeComputer extends AbstractComputer {
@Override
protected void login() {
System.out.print(
"程序员的电脑只需要用户和密码的验证就行");
}
}
<div class=
"se-preview-section-delimiter"></div>
具体流程改变(军事使用电脑类)
public class MilitaryComputer extends AbstractComputer {
@Override
protected void checkHardware() {
super.checkHardware();
System.out.println(
"检查硬件防火墙");
}
@Override
protected void login() {
System.out.println(
"进行指纹识别等复杂的用户实验");
}
}
<div class=
"se-preview-section-delimiter"></div>
测试使用
public class Test {
public static void main(String[] args){
AbstractComputer abstractComputer =
new CodeComputer();
abstractComputer.startUp();
abstractComputer =
new MilitaryComputer();
abstractComputer.startUp();
}
}
<div class=
"se-preview-section-delimiter"></div>
八. Builder模式
将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- 使用场景 1. 相同的方法,不同的执行顺序,产生不同的事件结果时。 2. 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同。 3. 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的作用,这个时候使用建造者模式非常合适。 4. 当初始化一个对象非常复杂,如参数多,且很多参数都有默认值的时候。
public abstract class Computer {
protected String mBoard;
protected String mDisplay;
protected String mOs;
public Computer() {
}
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 +
'\'' +
'}';
}
}
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();
public abstract Computer
create();
}
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;
}
}
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());
}
}
<div class=
"se-preview-section-delimiter"></div>
九:抽象工厂模式
简单代码实现
定义抽象工厂类
public abstract class CarFactory {
/**
* 生产轮胎
* @return 轮胎
*/
public abstract ITire
createTire();
/**
* 生产发动机
* @return 发动机
*/
public abstract IEngine
createEngine();
/**
* 生产制动系统
* @return 制动系统
*/
public abstract IBreak
createBreak();
}
<div class=
"se-preview-section-delimiter"></div>
各个细节的抽象
public interface ITire {
/**
* 轮胎
*/
void tire();
}
public interface IEngine {
/**
* 发动机
*/
void engine();
}
public interface IBreak {
/**
* 制动
* */
void bradk();
}
<div class=
"se-preview-section-delimiter"></div>
具体细节的实现
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(
"高级制动");
}
}
<div class=
"se-preview-section-delimiter"></div>
具体实现
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();
}
}
<div class=
"se-preview-section-delimiter"></div>
客户端的实现
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();
}
}
<div class=
"se-preview-section-delimiter"></div>
十:状态模式(电视遥控器)(开关Wi-Fi等等)
定义:当一个对象的内在状态改变的时允许改变起行为,这个对象看起来像是改变了其类。
使用场景:
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();
}
}
<div class=
"se-preview-section-delimiter"></div>
十一:观察者模式
定义:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
使用场景:
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;
}
}
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(
"新的一期开发技术周报发布啦!!!");
}
}
<div class=
"se-preview-section-delimiter"></div>
十二:适配器模式(姚明去NBA打篮球需要翻译)
定义:适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
使用场景:
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();
}
}
<div class=
"se-preview-section-delimiter"></div>
十三:备忘录模式
定义:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样,以后就可将该对象恢复到原先保存的状态。
应用场景:
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());
}
@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());
}
}
<div class=
"se-preview-section-delimiter"></div>
十四: 组合模式(View 和ViewGroup),公司故事
定义: 将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象使用的一致性。
使用场景:
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);
}
}
<div class=
"se-preview-section-delimiter"></div>
十五:迭代器模式
定义:提供一种方法顺序访问一个容器对象中的各个元素,而又不需要暴漏该对象的内部显示。
使用场景:
遍历一个容器对象时。
public interface Iterator {
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;
}
}
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);
}
}
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());
}
}
}
<div class=
"se-preview-section-delimiter"></div>
十六:单例模式。
懒汉模式
public class Signleton {
private static Signleton instance;
private Signleton() {
}
public static synchronized Signleton
getInstance() {
if (instance ==
null) {
instance =
new Signleton();
}
return instance;
}
}
<div class=
"se-preview-section-delimiter"></div>
Double Check Lock (DCL) 实现单例,
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 =
new Signleton();
}
}
}
return instance;
}
}
public class Signleton {
private Signleton() {
}
public static Signleton
getInstance() {
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Signleton sInstance =
new Signleton();
}
}
<div class=
"se-preview-section-delimiter"></div>
十七: 桥接模式
定义:将抽象部分与实现部分分离,使它们都可以独立的进行变化。
使用场景:
一个类存在两个独立变化的纬度,且这两个纬度都需要进行扩展。
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();
}
}
<div class=
"se-preview-section-delimiter"></div>
十八: 命令模式 (几乎体现了设计模式的所有的通病,就是类的膨胀)
定义:讲一个请求封装成一个对象,从而让用户使用不同的请求把客户端参数化;对请求拍队或者记录请求日志,以及支持可撤销的操作。
使用场景:
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();
LeftCommand leftCommand =
new LeftCommand(tetrisMachine);
RightCommand rightCommand =
new RightCommand(tetrisMachine);
Button button =
new Button();
button.setLeftCommand(leftCommand);
button.setRightCommand(rightCommand);
button.toLeft();
button.toRight();
}
}
<div class=
"se-preview-section-delimiter"></div>
敏捷开发原则告诉我们,不要为代码添加基于猜测的,实际不需要的功能,如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它。
可以直接实现:
public class Client {
public static void main(String[] args) {
TetrisMachine tetrisMachine =
new TetrisMachine();
tetrisMachine.toLeft();
tetrisMachine.toRight();
}
}
<div class=
"se-preview-section-delimiter"></div>
十九: 责任链模式:
定义:使多个对象都有机会处理请求,从而避免来请求的发送者和接收者之间的耦合关系。将这些对象连城一条链,并沿着这条链传递该请求,只到有对象处理它为止。
使用场景:
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);
}
}
<div class=
"se-preview-section-delimiter"></div>
二十: 中介者模式
定义: 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
使用场景:
1.当对象之间的交互操作很多且每个对象的行为操作都依赖彼此时,为防止在修改一对象的行为时,同时设计修改很多其他对象的行为,可采用中介者模式。
“`java // 抽象同事类 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());
}
}
<div class=
"se-preview-section-delimiter"></div>
二十二:访问者模式
定义:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
使用场景:
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看的报表 ===========");
report.showReport(
new CEOVisitor());
System.out.println(
"=========== 给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 );
}
}
}