├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── yadong
│ │ └── pattern
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── yadong
│ │ │ └── pattern
│ │ │ ├── MainActivity.java
│ │ │ ├── behavioral
│ │ │ ├── chain_of_responsibility
│ │ │ │ ├── Approver.java
│ │ │ │ ├── ArticleApprover.java
│ │ │ │ ├── Course.java
│ │ │ │ ├── StringUtils.java
│ │ │ │ ├── TestChainOfResponsibility.java
│ │ │ │ └── VideoApprover.java
│ │ │ ├── command
│ │ │ │ ├── CloseCourseVideoCommand.java
│ │ │ │ ├── Command.java
│ │ │ │ ├── CourseVideo.java
│ │ │ │ ├── OpenCourseVideoCommand.java
│ │ │ │ ├── Staff.java
│ │ │ │ └── TestCommand.java
│ │ │ ├── interpreter
│ │ │ │ ├── AddInterpreter.java
│ │ │ │ ├── Interpreter.java
│ │ │ │ ├── MultiInterpreter.java
│ │ │ │ ├── MyExpressionParser.java
│ │ │ │ ├── NumberInterpreter.java
│ │ │ │ ├── OperatorUtil.java
│ │ │ │ └── TestInterpreter.java
│ │ │ ├── iterator
│ │ │ │ ├── Course.java
│ │ │ │ ├── CourseAggregate.java
│ │ │ │ ├── CourseAggregateImpl.java
│ │ │ │ ├── CourseIterator.java
│ │ │ │ ├── CourseIteratorImpl.java
│ │ │ │ └── TestIterator.java
│ │ │ ├── mediator
│ │ │ │ ├── StudyGroup.java
│ │ │ │ ├── TestMediator.java
│ │ │ │ └── User.java
│ │ │ ├── memento
│ │ │ │ ├── Article.java
│ │ │ │ ├── ArticleMemento.java
│ │ │ │ ├── ArticleMementoManager.java
│ │ │ │ └── TestMemento.java
│ │ │ ├── observer
│ │ │ │ ├── GirlFriendObserver.java
│ │ │ │ ├── MessageObservable.java
│ │ │ │ ├── Observable.java
│ │ │ │ ├── Observer.java
│ │ │ │ └── ObserverTest.java
│ │ │ ├── state
│ │ │ │ ├── CourseVideoContext.java
│ │ │ │ ├── CourseVideoState.java
│ │ │ │ ├── PauseState.java
│ │ │ │ ├── PlayState.java
│ │ │ │ ├── SpeedState.java
│ │ │ │ ├── StopState.java
│ │ │ │ └── TestState.java
│ │ │ ├── strategy
│ │ │ │ ├── StrategyTest.java
│ │ │ │ ├── behaviour
│ │ │ │ │ ├── FlyBehaviour.java
│ │ │ │ │ ├── FlyImp.java
│ │ │ │ │ └── FlyNoWayImp.java
│ │ │ │ └── duck
│ │ │ │ │ ├── BaseDuck.java
│ │ │ │ │ ├── BeiJingDuck.java
│ │ │ │ │ └── GreenHeadDuck.java
│ │ │ ├── template_method
│ │ │ │ ├── ACourse.java
│ │ │ │ ├── DesignPatternCourse.java
│ │ │ │ ├── FECourse.java
│ │ │ │ └── TestTemplateMethod.java
│ │ │ └── visitor
│ │ │ │ ├── CodingCourse.java
│ │ │ │ ├── Course.java
│ │ │ │ ├── FreeCourse.java
│ │ │ │ ├── IVisitor.java
│ │ │ │ ├── TestVisitor.java
│ │ │ │ └── Visitor.java
│ │ │ ├── creational
│ │ │ ├── builder
│ │ │ │ ├── Person.java
│ │ │ │ └── TestBuilder.java
│ │ │ ├── factory_abstract
│ │ │ │ ├── TestFactoryAbstract.java
│ │ │ │ ├── base
│ │ │ │ │ ├── BaseCourseFactory.java
│ │ │ │ │ ├── BaseNote.java
│ │ │ │ │ └── BaseVideo.java
│ │ │ │ ├── java_course
│ │ │ │ │ ├── JavaCourseFactory.java
│ │ │ │ │ ├── JavaNote.java
│ │ │ │ │ └── JavaVideo.java
│ │ │ │ └── python_course
│ │ │ │ │ ├── PythonCourseFactory.java
│ │ │ │ │ ├── PythonNote.java
│ │ │ │ │ └── PythonVideo.java
│ │ │ ├── factory_method
│ │ │ │ ├── TestFactoryMethod.java
│ │ │ │ ├── base
│ │ │ │ │ ├── Factory.java
│ │ │ │ │ └── VideoProduct.java
│ │ │ │ ├── java_video
│ │ │ │ │ ├── JavaVideo.java
│ │ │ │ │ └── JavaVideoFactory.java
│ │ │ │ └── python_video
│ │ │ │ │ ├── PythonVideo.java
│ │ │ │ │ └── PythonVideoFactory.java
│ │ │ ├── factory_simple
│ │ │ │ ├── BaseVideo.java
│ │ │ │ ├── JavaVideo.java
│ │ │ │ ├── PythonVideo.java
│ │ │ │ ├── TestFactorySimple.java
│ │ │ │ └── VideoFactory.java
│ │ │ ├── prototype
│ │ │ │ ├── TestPrototype.java
│ │ │ │ ├── deep_clone
│ │ │ │ │ └── Pig.java
│ │ │ │ └── shallow_clone
│ │ │ │ │ ├── Mail.java
│ │ │ │ │ └── MailUtil.java
│ │ │ └── single
│ │ │ │ ├── ContainerSingleton.java
│ │ │ │ ├── EnumInstance.java
│ │ │ │ ├── HungrySingleton.java
│ │ │ │ ├── LazyDoubleCheckSingleton.java
│ │ │ │ ├── StaticInnerClassSingleton.java
│ │ │ │ └── TestSingleton.java
│ │ │ └── structural
│ │ │ ├── adapter
│ │ │ ├── TestAdapter.java
│ │ │ ├── class_adapter
│ │ │ │ ├── Adaptee.java
│ │ │ │ ├── Adapter.java
│ │ │ │ ├── ConcreteTarget.java
│ │ │ │ └── Target.java
│ │ │ ├── object_adapter
│ │ │ │ ├── Adaptee.java
│ │ │ │ ├── Adapter.java
│ │ │ │ ├── ConcreteTarget.java
│ │ │ │ └── Target.java
│ │ │ └── voltage_adapter
│ │ │ │ ├── AC220.java
│ │ │ │ ├── DC5.java
│ │ │ │ └── PowerAdapter.java
│ │ │ ├── bridge
│ │ │ ├── ABCBank.java
│ │ │ ├── Account.java
│ │ │ ├── Bank.java
│ │ │ ├── DepositAccount.java
│ │ │ ├── ICBCBank.java
│ │ │ ├── SavingAccount.java
│ │ │ └── TestBridge.java
│ │ │ ├── composite
│ │ │ ├── CatalogComponent.java
│ │ │ ├── Course.java
│ │ │ ├── CourseCatalog.java
│ │ │ └── TestComposite.java
│ │ │ ├── decorator
│ │ │ ├── DecoratorTest.java
│ │ │ ├── v1
│ │ │ │ ├── BatterCake.java
│ │ │ │ ├── BatterCakeWithEgg.java
│ │ │ │ └── BatterCakeWithEggSausage.java
│ │ │ └── v2
│ │ │ │ ├── ABatterCake.java
│ │ │ │ ├── AbstractDecorator.java
│ │ │ │ ├── BatterCake.java
│ │ │ │ ├── EggDecorator.java
│ │ │ │ └── SausageDecorator.java
│ │ │ ├── facade
│ │ │ ├── GiftExchangeService.java
│ │ │ ├── LogisticsService.java
│ │ │ ├── PointGift.java
│ │ │ ├── PointsPaymentService.java
│ │ │ ├── QualifyService.java
│ │ │ └── TestFacade.java
│ │ │ ├── flyweight
│ │ │ ├── Employee.java
│ │ │ ├── EmployeeFactory.java
│ │ │ ├── Manager.java
│ │ │ └── TestFlyweight.java
│ │ │ └── proxy
│ │ │ ├── AddController.java
│ │ │ ├── ContactController.java
│ │ │ ├── DataInterface.java
│ │ │ └── ProxyTest.java
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── yadong
│ └── pattern
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | .DS_Store
6 | /build
7 | /captures
8 | .externalNativeBuild
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Design Patterns(设计模式)
2 |
3 | ### 设计原则:
4 | * 单一职责原则 Single Responsibility Principle
5 | * 对扩展开放,对修改关闭
6 |
7 | ### 创建型模式
8 | * [简单工厂模式(Simple Factoty)](https://www.jianshu.com/p/ceb5131b5953)
9 | * [工厂方法模式(Method Factoty)](https://www.jianshu.com/p/4fbe55b172b7)
10 | * [抽象工厂模式(Abstarct Factory)](https://www.jianshu.com/p/84a253651b21)
11 | * [建造者模式(Builder)](https://www.jianshu.com/p/c7541ce6672a)
12 | >用于创建复合对象
13 | * [单例模式(Singleton)](https://www.jianshu.com/p/e0831dad87b5)
14 | * [原型模式(prototype)](https://www.jianshu.com/p/c16ef296c1f9)
15 | >对象的拷贝
16 |
17 | ### 结构型模式
18 | * [外观模式(facade)](https://www.jianshu.com/p/3241c99e0724)
19 | >简化接口,降低复杂性(ps: 即定义一个高级接口,操作一系列接口)
20 | * [装饰器模式(decorator)](https://www.jianshu.com/p/a21c3599fe5e)
21 | >不改变接口的情况下,添加责任;
22 | 例子 javaI/O
23 | * [适配器模式(adapter)](https://www.jianshu.com/p/acc82da59762)
24 | >接口转换
25 | * [享元模式(Flyweight)](https://www.jianshu.com/p/8e6d4a692a56)
26 | >采用一个共享来避免大量拥有相同内容对象的开销
27 | * [组合模式(composite)](https://www.jianshu.com/p/bc973a1c024a)
28 | >对象组合成树状结构,实现统一处理个别对象及对象组合
29 | * [桥接模式(bridge)](https://www.jianshu.com/p/fc82a284177e)
30 | >主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,
31 | 从而可以保持各部分的独立性以及应对它们的功能扩展
32 | * [代理模式(proxy)](https://www.jianshu.com/p/19a1abb629b0)
33 | >为另一个对象提供一个对象或占位符以控制对这个对象的访问
34 |
35 | ### 行为型模式
36 | * [模板方法模式(template)](https://www.jianshu.com/p/380a437f7303)
37 | >在一个方法内定义一个算法的骨架,具体算法步骤有由子类实现,
38 | 例如:数组的 sort方法
39 | * [迭代器模式(Iterator pattern)](https://www.jianshu.com/p/0ad3521cc4fa)
40 | >提供统一的方法顺序访问聚合对象的每个元素,而又不暴露内部细节;
41 | * [策略模式(strategy pattern)](https://www.jianshu.com/p/cdfe4c5041af)
42 | > 定义算法族,分别封装,各算法间可相互替换,一般由调用算法族的类组合算法
43 | 与状态模式类似,都可以动态改变行为(算法)区别在于状态模式由状态类控制行为的改变
44 | * [解释器模式(interpreter)](https://www.jianshu.com/p/be983cc8706b)
45 | >用于解析语法树
46 | * [观察者模式(Observer)](https://www.jianshu.com/p/f1a93aec7068)
47 | * [备忘录模式(memento)](https://www.jianshu.com/p/9e853a4c4905)
48 | >存储一个对象的内部状态,用于恢复;
49 | 发起人:记录当前内部状态;定义备份的范围,负责创建和恢复数据;
50 | 备忘录:负责存储状态;
51 | 管理者:对备忘录进行管理
52 | * [命令模式(command)](https://www.jianshu.com/p/6fc9f869a935)
53 | * [中介者模式(mediator)](https://www.jianshu.com/p/54989f21022e)
54 | >用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互
55 | * [责任链模式(Chain of Responsibility)](https://www.jianshu.com/p/3f0a7835dbe9)
56 | >很多对象由每一个对象对其下家的引用而连接起来形成一条链
57 | 例如:对申请审批的流转,权限不足向上流转直达有满足权限的人处理
58 | * [访问者模式(visitor)](https://www.jianshu.com/p/33b8cdc608fb)
59 | >(方法重载)根据访问者的不同执行不同的方法
60 | * [状态模式(Pattern of Objects for States)](https://www.jianshu.com/p/7dfe1e21ebd6)
61 | >允许对象在内部状态改变是改变他的行为;行为的改变一般由状态类控制
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | defaultConfig {
6 | applicationId "com.yadong.pattern"
7 | minSdkVersion 16
8 | targetSdkVersion 27
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation fileTree(dir: 'libs', include: ['*.jar'])
23 | implementation 'com.android.support:appcompat-v7:27.1.1'
24 | implementation 'com.android.support.constraint:constraint-layout:1.1.2'
25 | testImplementation 'junit:junit:4.12'
26 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
27 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
28 | }
29 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/yadong/pattern/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.yadong.pattern", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.view.View;
6 |
7 | import com.yadong.pattern.behavioral.chain_of_responsibility.TestChainOfResponsibility;
8 | import com.yadong.pattern.behavioral.command.TestCommand;
9 | import com.yadong.pattern.behavioral.interpreter.TestInterpreter;
10 | import com.yadong.pattern.behavioral.iterator.TestIterator;
11 | import com.yadong.pattern.behavioral.mediator.TestMediator;
12 | import com.yadong.pattern.behavioral.memento.TestMemento;
13 | import com.yadong.pattern.behavioral.state.TestState;
14 | import com.yadong.pattern.behavioral.template_method.TestTemplateMethod;
15 | import com.yadong.pattern.behavioral.visitor.TestVisitor;
16 | import com.yadong.pattern.creational.builder.TestBuilder;
17 | import com.yadong.pattern.structural.adapter.TestAdapter;
18 | import com.yadong.pattern.structural.bridge.TestBridge;
19 | import com.yadong.pattern.structural.composite.TestComposite;
20 | import com.yadong.pattern.structural.decorator.DecoratorTest;
21 | import com.yadong.pattern.structural.facade.TestFacade;
22 | import com.yadong.pattern.creational.factory_abstract.TestFactoryAbstract;
23 | import com.yadong.pattern.creational.factory_method.TestFactoryMethod;
24 | import com.yadong.pattern.creational.factory_simple.TestFactorySimple;
25 | import com.yadong.pattern.behavioral.observer.ObserverTest;
26 | import com.yadong.pattern.creational.prototype.TestPrototype;
27 | import com.yadong.pattern.structural.flyweight.TestFlyweight;
28 | import com.yadong.pattern.structural.proxy.ProxyTest;
29 | import com.yadong.pattern.creational.single.TestSingleton;
30 | import com.yadong.pattern.behavioral.strategy.StrategyTest;
31 |
32 | import java.util.ArrayList;
33 |
34 | /**
35 | * 设计模式大全
36 | *
37 | * 创建型模式
38 | * |1---简单工厂模式(它不属于23种设计模式)
39 | * |2---工厂方法模式
40 | * |3---抽象工厂模式
41 | * |4---建造者模式
42 | * |5---单例模式
43 | * |6---原型模式
44 | *
45 | * 结构型模式
46 | * |7---外观模式
47 | * |8---装饰器模式
48 | * |9---适配器模式
49 | * |10---享元模式
50 | * |11---组合模式
51 | * |12---桥接模式
52 | * |13---代理模式
53 | *
54 | * 行为型模式
55 | * |14---模板方法模式
56 | * |15---迭代器模式
57 | * |16---策略模式
58 | * |17---解释器模式
59 | * |18---观察者模式
60 | * |19---备忘录模式
61 | * |20---命令模式
62 | * |21---中介者模式
63 | * |22---责任链模式
64 | * |23---访问者模式
65 | * |24---状态模式
66 | */
67 | public class MainActivity extends AppCompatActivity {
68 |
69 | @Override
70 | protected void onCreate(Bundle savedInstanceState) {
71 | super.onCreate(savedInstanceState);
72 | setContentView(R.layout.activity_main);
73 | }
74 |
75 | /**
76 | * 测试按钮
77 | */
78 | public void testClick(View view) throws Exception {
79 | // method1();
80 | // method2();
81 | // method3();
82 | // method4();
83 | // method5();
84 | // method6();
85 | // method7();
86 | // method8();
87 | // method9();
88 | // method10();
89 | // method11();
90 | // method12();
91 | // method13();
92 | // method14();
93 | // method15();
94 | // method16();
95 | // method17();
96 | // method18();
97 | // method19();
98 | // method20();
99 | // method21();
100 | // method22();
101 | // method23();
102 | method24();
103 | }
104 |
105 | /*******************创建型模式***********************************************/
106 | /**
107 | * 简单工厂,它不属于GOF23种设计模式
108 | */
109 | public void method1() {
110 | TestFactorySimple.test();
111 | }
112 |
113 | /**
114 | * 工厂方法
115 | */
116 | public void method2() {
117 | TestFactoryMethod.test();
118 | }
119 |
120 |
121 | /**
122 | * 抽象工厂
123 | */
124 | public void method3() {
125 | TestFactoryAbstract.test();
126 | }
127 |
128 | /**
129 | * 建造者模式
130 | */
131 | public void method4() {
132 | TestBuilder.test();
133 | }
134 |
135 | /**
136 | * 单例设计模式
137 | */
138 | public void method5() throws Exception {
139 | TestSingleton.test();
140 | }
141 |
142 | /**
143 | * 原型模式
144 | */
145 | public void method6() throws Exception {
146 | TestPrototype.test();
147 | }
148 |
149 |
150 | /*******************结构型模式*******************************************************************/
151 | /**
152 | * 外观模式
153 | */
154 | public void method7() {
155 | TestFacade.test();
156 | }
157 |
158 | /**
159 | * 装饰器模式
160 | */
161 | public void method8() {
162 | DecoratorTest.testV2();
163 | }
164 |
165 | /**
166 | * 适配器模式
167 | */
168 | public void method9() {
169 | TestAdapter.classAdapterTest();
170 | TestAdapter.objectAdapterTest();
171 | TestAdapter.powerAdapter();
172 | }
173 |
174 | /**
175 | * 享元模式
176 | */
177 | public void method10() {
178 | TestFlyweight.test();
179 | }
180 |
181 | /**
182 | * 组合模式
183 | */
184 | public void method11() {
185 | TestComposite.test();
186 | }
187 |
188 | /**
189 | * 桥接模式
190 | */
191 | public void method12() {
192 | TestBridge.test();
193 | }
194 |
195 | /**
196 | * 代理模式
197 | */
198 | public void method13() {
199 | ProxyTest.test();
200 | }
201 |
202 | /*******************行为型模式*******************************************************************/
203 | /**
204 | * 模板方法模式
205 | */
206 | public void method14() {
207 | TestTemplateMethod.test();
208 | }
209 |
210 | /**
211 | * 迭代器模式
212 | */
213 | public void method15() {
214 | TestIterator.test();
215 | }
216 |
217 | /**
218 | * 策略模式
219 | */
220 | public void method16() {
221 | StrategyTest.test();
222 | }
223 |
224 | /**
225 | * 解释器模式
226 | */
227 | public void method17() {
228 | TestInterpreter.test();
229 | }
230 |
231 | /**
232 | * 观察者模式
233 | */
234 | public void method18() {
235 | ObserverTest.test();
236 | }
237 |
238 | /**
239 | * 备忘录模式
240 | */
241 | public void method19() {
242 | TestMemento.test();
243 | }
244 |
245 | /**
246 | * 命令模式
247 | */
248 | public void method20() {
249 | TestCommand.test();
250 | }
251 |
252 | /**
253 | * 中介者模式
254 | */
255 | public void method21() {
256 | TestMediator.test();
257 | }
258 |
259 | /**
260 | * 责任链模式
261 | */
262 | public void method22() {
263 | TestChainOfResponsibility.test();
264 | }
265 |
266 | /**
267 | * 访问者模式
268 | */
269 | public void method23() {
270 | TestVisitor.test();
271 | }
272 |
273 |
274 |
275 | /**
276 | * 状态模式
277 | */
278 | public void method24() {
279 | TestState.test();
280 | }
281 |
282 | public void show(){
283 |
284 |
285 | }
286 |
287 |
288 | }
289 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/chain_of_responsibility/Approver.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.chain_of_responsibility;
2 |
3 | /**
4 | * 创建抽象的批准者类
5 | */
6 | public abstract class Approver {
7 | protected Approver approver;
8 |
9 | public void setNextApprover(Approver approver){
10 | this.approver = approver;
11 | }
12 | public abstract void deploy(Course course);
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/chain_of_responsibility/ArticleApprover.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.chain_of_responsibility;
2 |
3 |
4 | /**
5 | * 手记批准者
6 | */
7 | public class ArticleApprover extends Approver {
8 | @Override
9 | public void deploy(Course course) {
10 | if (StringUtils.isNotEmpty(course.getArticle())) {
11 | System.out.println(course.getName() + "含有手记,批准");
12 | if (approver != null) {
13 | approver.deploy(course);
14 | }
15 | } else {
16 | System.out.println(course.getName() + "不含有手记,不批准,流程结束");
17 | return;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/chain_of_responsibility/Course.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.chain_of_responsibility;
2 |
3 | /**
4 | *课程
5 | */
6 | public class Course {
7 | private String name;
8 | private String article;
9 | private String video;
10 |
11 | public String getName() {
12 | return name;
13 | }
14 |
15 | public void setName(String name) {
16 | this.name = name;
17 | }
18 |
19 | public String getArticle() {
20 | return article;
21 | }
22 |
23 | public void setArticle(String article) {
24 | this.article = article;
25 | }
26 |
27 | public String getVideo() {
28 | return video;
29 | }
30 |
31 | public void setVideo(String video) {
32 | this.video = video;
33 | }
34 |
35 | @Override
36 | public String toString() {
37 | return "Course{" +
38 | "name='" + name + '\'' +
39 | ", article='" + article + '\'' +
40 | ", video='" + video + '\'' +
41 | '}';
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/chain_of_responsibility/StringUtils.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.chain_of_responsibility;
2 |
3 | public class StringUtils {
4 |
5 | public static boolean isNotEmpty(String str) {
6 | return str != null && str.length() > 0;
7 | }
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/chain_of_responsibility/TestChainOfResponsibility.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.chain_of_responsibility;
2 |
3 |
4 | /**
5 | * 责任链模式
6 | * 定义:为请求创建一个接受此次请求对象的链
7 | * 类型:行为型
8 | *
9 | * 适用场景:
10 | * 1.一个请求的处理需要多个对象当中的一个或几个协作处理
11 | * 优点:
12 | * 1.请求的发送者和接受者(请求的处理者)解耦
13 | * 2.责任链可以动态组合
14 | * 缺点:
15 | * 1.责任链太长或者处理时间过长,影响性能
16 | * 2.责任链有可能过多
17 | *
18 | */
19 | public class TestChainOfResponsibility {
20 |
21 | /**
22 | * 在网站上发布一个课程,需要两个人检查,一个是视频,一个是手记
23 | */
24 | public static void test() {
25 | //创建手记批准者
26 | Approver articleApprover = new ArticleApprover();
27 | //创建视频批准者
28 | Approver videoApprover = new VideoApprover();
29 |
30 | //创建课程
31 | Course course = new Course();
32 | course.setName("Java设计模式精讲");
33 | course.setArticle("Java设计模式精讲的手记");
34 | course.setVideo("Java设计模式精讲的视频");
35 |
36 | //校验
37 | articleApprover.setNextApprover(videoApprover);
38 | articleApprover.deploy(course);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/chain_of_responsibility/VideoApprover.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.chain_of_responsibility;
2 |
3 |
4 | /**
5 | *视频批准者
6 | */
7 | public class VideoApprover extends Approver {
8 | @Override
9 | public void deploy(Course course) {
10 |
11 | if (StringUtils.isNotEmpty(course.getVideo())) {
12 | System.out.println(course.getName() + "含有视频,批准");
13 | if (approver != null) {
14 | approver.deploy(course);
15 | }
16 | } else {
17 | System.out.println(course.getName() + "不含有视频,不批准,流程结束");
18 | return;
19 | }
20 | }
21 |
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/command/CloseCourseVideoCommand.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.command;
2 |
3 | /**
4 | * 第3步
5 | * 关闭课程视频命令
6 | */
7 | public class CloseCourseVideoCommand implements Command {
8 | private CourseVideo courseVideo;
9 |
10 | public CloseCourseVideoCommand(CourseVideo courseVideo) {
11 | this.courseVideo = courseVideo;
12 | }
13 |
14 | @Override
15 | public void execute() {
16 | courseVideo.close();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/command/Command.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.command;
2 |
3 | /**
4 | * 第1步
5 | * 命令接口
6 | */
7 | public interface Command {
8 | void execute();
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/command/CourseVideo.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.command;
2 |
3 | /**
4 | * 第2步
5 | * 创建课程视频
6 | */
7 | public class CourseVideo {
8 | private String name;
9 |
10 | public CourseVideo(String name) {
11 | this.name = name;
12 | }
13 | public void open(){
14 | System.out.println(this.name+"课程视频开放");
15 | }
16 | public void close(){
17 | System.out.println(this.name+"课程视频关闭");
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/command/OpenCourseVideoCommand.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.command;
2 |
3 | /**
4 | * 第3步
5 | * 打开课程视频命令
6 | */
7 | public class OpenCourseVideoCommand implements Command {
8 | private CourseVideo courseVideo;
9 |
10 | public OpenCourseVideoCommand(CourseVideo courseVideo) {
11 | this.courseVideo = courseVideo;
12 | }
13 |
14 | @Override
15 | public void execute() {
16 | courseVideo.open();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/command/Staff.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.command;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 第4步,创建工作人员类
8 | * 可以执行一组命令
9 | */
10 | public class Staff {
11 | private List commandList = new ArrayList<>();
12 | public void addCommand(Command command){
13 | commandList.add(command);
14 | }
15 |
16 | public void executeCommands(){
17 | for(Command command : commandList){
18 | command.execute();
19 | }
20 | commandList.clear();
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/command/TestCommand.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.command;
2 |
3 |
4 | /**
5 | * 命令模式
6 | * 定义:将请求封装成对象,以便使用不同的请求
7 | * 特征:命令模式解决了应用程序中对象的职责和它们之间的通信方式
8 | * 类型:行为型
9 | *
10 | * 适用场景:
11 | * 1.请求的调用者和请求接受者需要解耦,使得调用者和接受者不直接交互
12 | * 2.需要抽象出等待执行的行为
13 | * 优点:
14 | * 1.降低耦合
15 | * 2.容易扩展新命令或者一组命令
16 | * 缺点:
17 | * 1.命令的无限扩展会增加类的数量,提高系统的实现复杂度
18 | *
19 | */
20 | public class TestCommand {
21 |
22 | /**
23 | * 场景:网站上课程是有视频的,免费打开视频让大家看或者关闭这个视频收费才能看
24 | */
25 | public static void test() {
26 | //创建课程
27 | CourseVideo courseVideo = new CourseVideo("Java设计模式");
28 | //创建打开命令
29 | OpenCourseVideoCommand openCourseVideoCommand = new OpenCourseVideoCommand(courseVideo);
30 | //创建关闭命令
31 | CloseCourseVideoCommand closeCourseVideoCommand = new CloseCourseVideoCommand(courseVideo);
32 |
33 | //创建工作人员
34 | Staff staff = new Staff();
35 | staff.addCommand(openCourseVideoCommand);
36 | staff.addCommand(closeCourseVideoCommand);
37 |
38 | //执行这一组命令
39 | staff.executeCommands();
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/interpreter/AddInterpreter.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.interpreter;
2 |
3 | /**
4 | * 加法解释器 实现解释器接口
5 | */
6 | public class AddInterpreter implements Interpreter {
7 | private Interpreter firstExpression, secondExpression;
8 |
9 | public AddInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
10 | this.firstExpression = firstExpression;
11 | this.secondExpression = secondExpression;
12 | }
13 |
14 | @Override
15 | public int interpret() {
16 | return this.firstExpression.interpret() + this.secondExpression.interpret();
17 | }
18 |
19 | @Override
20 | public String toString() {
21 | return "+";
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/interpreter/Interpreter.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.interpreter;
2 |
3 | /**
4 | * 解释器接口
5 | */
6 | public interface Interpreter {
7 | int interpret();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/interpreter/MultiInterpreter.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.interpreter;
2 |
3 | /**
4 | * 乘法解释器 实现解释器接口
5 | */
6 | public class MultiInterpreter implements Interpreter {
7 |
8 | private Interpreter firstExpression,secondExpression;
9 | public MultiInterpreter(Interpreter firstExpression, Interpreter secondExpression){
10 | this.firstExpression=firstExpression;
11 | this.secondExpression=secondExpression;
12 | }
13 | @Override
14 | public int interpret(){
15 | return this.firstExpression.interpret()*this.secondExpression.interpret();
16 | }
17 | @Override
18 | public String toString(){
19 | return "*";
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/interpreter/MyExpressionParser.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.interpreter;
2 |
3 | import java.util.Stack;
4 |
5 | /**
6 | * 自定义解释器,去解释字符串
7 | */
8 | public class MyExpressionParser {
9 | private Stack stack = new Stack();
10 |
11 | public int parse(String str) {
12 | String[] strItemArray = str.split(" ");
13 | for (String symbol : strItemArray) {
14 | if (!OperatorUtil.isOperator(symbol)) {
15 | Interpreter numberExpression = new NumberInterpreter(symbol);
16 | stack.push(numberExpression);
17 | System.out.println(String.format("入栈: %d", numberExpression.interpret()));
18 | } else {
19 | //是运算符号,可以计算
20 | Interpreter firstExpression = stack.pop();
21 | Interpreter secondExpression = stack.pop();
22 | System.out.println(String.format("出栈: %d 和 %d",
23 | firstExpression.interpret(), secondExpression.interpret()));
24 | Interpreter operator = OperatorUtil.getExpressionObject(firstExpression, secondExpression, symbol);
25 | System.out.println(String.format("应用运算符: %s", operator));
26 | int result = operator.interpret();
27 | NumberInterpreter resultExpression = new NumberInterpreter(result);
28 | stack.push(resultExpression);
29 | System.out.println(String.format("阶段结果入栈: %d", resultExpression.interpret()));
30 | }
31 | }
32 | int result = stack.pop().interpret();
33 | return result;
34 |
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/interpreter/NumberInterpreter.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.interpreter;
2 |
3 | /**
4 | * 数字解释器 实现解释器接口
5 | */
6 | public class NumberInterpreter implements Interpreter {
7 | private int number;
8 |
9 | public NumberInterpreter(int number) {
10 | this.number = number;
11 | }
12 |
13 | public NumberInterpreter(String number) {
14 | this.number = Integer.parseInt(number);
15 | }
16 |
17 | @Override
18 | public int interpret() {
19 | return this.number;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/interpreter/OperatorUtil.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.interpreter;
2 |
3 | /**
4 | * 工具类
5 | */
6 | public class OperatorUtil {
7 | public static boolean isOperator(String symbol) {
8 | return (symbol.equals("+") || symbol.equals("*"));
9 | }
10 |
11 | public static Interpreter getExpressionObject(Interpreter firstExpression, Interpreter secondExpression, String symbol) {
12 | if (symbol.equals("+")) {
13 | return new AddInterpreter(firstExpression, secondExpression);
14 | } else if (symbol.equals("*")) {
15 | return new MultiInterpreter(firstExpression, secondExpression);
16 | }
17 | return null;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/interpreter/TestInterpreter.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.interpreter;
2 |
3 | /**
4 | * 解释器模式
5 | * 定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
6 | * 特征:为了解释一种语言,而为语言创建的解释器
7 | * 类型:行为型
8 | *
9 | * 适用场景:
10 | * 1.某个特定类型问题发生频率足够高
11 | * 优点:
12 | * 1.语法由很多类表示,容易改变和扩展此"语言"
13 | * 缺点:
14 | * 1.当语法规则数目太多时,增加了系统复杂度
15 | *
16 | * 非常低频的一个设计模式
17 | */
18 | public class TestInterpreter {
19 |
20 |
21 | /**
22 | * 场景:输入一个字符串,通过自定义解释器,去得到一个结果
23 | */
24 | public static void test() {
25 | //输入字符串,自己定义的一套算法
26 | String geelyInputStr="6 100 11 + *";
27 | MyExpressionParser expressionParser=new MyExpressionParser();
28 | int result=expressionParser.parse(geelyInputStr);
29 | /**
30 | * 结果:
31 | * 100+11=111 111*6=666
32 | */
33 | System.out.println("解释器计算结果: "+result);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/iterator/Course.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.iterator;
2 |
3 | /**
4 | * 课程的实体类
5 | */
6 | public class Course {
7 | private String name;
8 |
9 | public Course(String name) {
10 | this.name = name;
11 | }
12 |
13 | public String getName() {
14 | return name;
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/iterator/CourseAggregate.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.iterator;
2 |
3 | /**
4 | * 课程的集合 接口
5 | */
6 | public interface CourseAggregate {
7 |
8 | /**
9 | * 添加课程
10 | */
11 | void addCourse(Course course);
12 |
13 | /**
14 | * 删除课程
15 | */
16 | void removeCourse(Course course);
17 |
18 | /**
19 | * 课程迭代器
20 | */
21 | CourseIterator getCourseIterator();
22 |
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/iterator/CourseAggregateImpl.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.iterator;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 课程的集合 的实现类
8 | */
9 | public class CourseAggregateImpl implements CourseAggregate {
10 |
11 | private List courseList;
12 |
13 | public CourseAggregateImpl() {
14 | this.courseList = new ArrayList();
15 | }
16 |
17 | @Override
18 | public void addCourse(Course course) {
19 | courseList.add(course);
20 | }
21 |
22 | @Override
23 | public void removeCourse(Course course) {
24 | courseList.remove(course);
25 | }
26 |
27 | @Override
28 | public CourseIterator getCourseIterator() {
29 | return new CourseIteratorImpl(courseList);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/iterator/CourseIterator.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.iterator;
2 |
3 | /**
4 | * 课程迭代器的接口类
5 | */
6 | public interface CourseIterator {
7 | /**
8 | * 获取下个一个课程
9 | */
10 | Course nextCourse();
11 |
12 | /**
13 | * 是不是下一个课程
14 | */
15 | boolean isLastCourse();
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/iterator/CourseIteratorImpl.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.iterator;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * 课程迭代器的实现类
7 | */
8 | public class CourseIteratorImpl implements CourseIterator {
9 |
10 | private List courseList;
11 | private int position;
12 | private Course course;
13 | public CourseIteratorImpl(List courseList){
14 | this.courseList=courseList;
15 | }
16 |
17 | @Override
18 | public Course nextCourse() {
19 | System.out.println("返回课程,位置是: "+position);
20 | course=(Course)courseList.get(position);
21 | position++;
22 | return course;
23 | }
24 |
25 | @Override
26 | public boolean isLastCourse(){
27 | if(position< courseList.size()){
28 | return false;
29 | }
30 | return true;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/iterator/TestIterator.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.iterator;
2 |
3 | /**
4 | * 迭代器模式
5 | * 定义:提供一种方法,顺序访问一个集合对象中的各个元素,而又不暴露该对象的内部表示
6 | * 类型:行为型
7 | *
8 | * 适用场景:
9 | * 1.访问一个集合对象的内容而无需暴露它的内部表示
10 | * 2.为遍历不同的集合结构提供一个统一的接口
11 | * 优点:
12 | * 1.分离了集合对象的遍历行为
13 | * 缺点:
14 | * 1.类的个数成对增加
15 | */
16 | public class TestIterator {
17 |
18 |
19 | /**
20 | * 其实迭代器模式一般自己手动实现的不多,都是用的别人写好的
21 | * 场景:网上有很多学习Java的课程
22 | * 目的:然后想通过迭代器模式去进行遍历并打印
23 | */
24 | public static void test(){
25 | //创建3个课程
26 | Course course1 = new Course("Java基础");
27 | Course course2 = new Course("Android基础");
28 | Course course3 = new Course("Java设计模式");
29 |
30 | //把这3个课程添加到课程集合类中
31 | CourseAggregate courseAggregate = new CourseAggregateImpl();
32 | courseAggregate.addCourse(course1);
33 | courseAggregate.addCourse(course2);
34 | courseAggregate.addCourse(course3);
35 |
36 |
37 | System.out.println("-----课程列表-----");
38 | printCourses(courseAggregate);
39 | //删除课程3(Java设计模式)
40 | courseAggregate.removeCourse(course3);
41 | System.out.println("-----删除操作之后的课程列表-----");
42 | printCourses(courseAggregate);
43 | }
44 |
45 | /**
46 | * 遍历迭代器并打印课程的名字
47 | */
48 | public static void printCourses(CourseAggregate courseAggregate){
49 | CourseIterator courseIterator= courseAggregate.getCourseIterator();
50 | while(!courseIterator.isLastCourse()){
51 | Course course=courseIterator.nextCourse();
52 | System.out.println(course.getName());
53 | }
54 | }
55 |
56 |
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/mediator/StudyGroup.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.mediator;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * 中介者,可以理解为一个群,大家都可以在这里面说话
7 | */
8 | public class StudyGroup {
9 |
10 | public static void showMessage(User user, String message){
11 | System.out.println(new Date().toString() + " [" + user.getName() + "] : " + message);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/mediator/TestMediator.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.mediator;
2 |
3 |
4 | /**
5 | * 中介者模式
6 | * 定义:定义一个封装一组对象如何交互的对象
7 | * 特征:通过使对象明确的相互引用来促进松散耦合,并允许独立的改变他们的交互
8 | * 类型:行为型
9 | *
10 | * 适用场景:
11 | * 1.系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解
12 | * 2.交互的公共行为,如果需要改变行为则可以增加新的中介者类
13 | * 优点:
14 | * 1.将一对多转化成了一对一,降低程序复杂度
15 | * 2.类之间解耦
16 | * 缺点:
17 | * 1.中介者过多,导致系统复杂
18 | */
19 | public class TestMediator {
20 |
21 | /**
22 | * 风清扬和令狐冲交流,传授独孤九剑
23 | */
24 | public static void test() {
25 |
26 | User fengqingyang = new User("风清扬");
27 | User linghuchong = new User("令狐冲");
28 |
29 | fengqingyang.sendMessage("传授你独孤九剑");
30 | linghuchong.sendMessage("OK");
31 | }
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/mediator/User.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.mediator;
2 |
3 | /**
4 | *
5 | */
6 | public class User {
7 | private String name;
8 |
9 | public String getName() {
10 | return name;
11 | }
12 |
13 | public void setName(String name) {
14 | this.name = name;
15 | }
16 |
17 | public User(String name) {
18 | this.name = name;
19 | }
20 |
21 | /**
22 | * 交给中介者展示信息
23 | * @param message
24 | */
25 | public void sendMessage(String message) {
26 | StudyGroup.showMessage(this, message);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/memento/Article.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.memento;
2 |
3 | /**
4 | * 手记
5 | */
6 | public class Article {
7 |
8 | private String title;
9 | private String content;
10 | private String imgs;
11 |
12 | public Article(String title, String content, String imgs) {
13 | this.title = title;
14 | this.content = content;
15 | this.imgs = imgs;
16 | }
17 |
18 | public String getTitle() {
19 | return title;
20 | }
21 |
22 | public void setTitle(String title) {
23 | this.title = title;
24 | }
25 |
26 | public String getContent() {
27 | return content;
28 | }
29 |
30 | public void setContent(String content) {
31 | this.content = content;
32 | }
33 |
34 | public String getImgs() {
35 | return imgs;
36 | }
37 |
38 | public void setImgs(String imgs) {
39 | this.imgs = imgs;
40 | }
41 |
42 | /**
43 | * 保存到备忘录中
44 | */
45 | public ArticleMemento saveToMemento() {
46 | ArticleMemento articleMemento = new ArticleMemento(this.title, this.content, this.imgs);
47 | return articleMemento;
48 | }
49 |
50 | public void undoFromMemento(ArticleMemento articleMemento) {
51 | this.title = articleMemento.getTitle();
52 | this.content = articleMemento.getContent();
53 | this.imgs = articleMemento.getImgs();
54 | }
55 |
56 | @Override
57 | public String toString() {
58 | return "Article{" +
59 | "title='" + title + '\'' +
60 | ", content='" + content + '\'' +
61 | ", imgs='" + imgs + '\'' +
62 | '}';
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/memento/ArticleMemento.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.memento;
2 |
3 | /**
4 | * 手记备忘
5 | */
6 | public class ArticleMemento {
7 | private String title;
8 | private String content;
9 | private String imgs;
10 |
11 | public ArticleMemento(String title, String content, String imgs) {
12 | this.title = title;
13 | this.content = content;
14 | this.imgs = imgs;
15 | }
16 |
17 | public String getTitle() {
18 | return title;
19 | }
20 |
21 | public String getContent() {
22 | return content;
23 | }
24 |
25 | public String getImgs() {
26 | return imgs;
27 | }
28 |
29 | @Override
30 | public String toString() {
31 | return "ArticleMemento{" +
32 | "title='" + title + '\'' +
33 | ", content='" + content + '\'' +
34 | ", imgs='" + imgs + '\'' +
35 | '}';
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/memento/ArticleMementoManager.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.memento;
2 |
3 | import java.util.Stack;
4 |
5 | /**
6 | * 手记备忘管理者
7 | */
8 | public class ArticleMementoManager {
9 |
10 | private final Stack ARTICLE_MEMENTO_STACK = new Stack<>();
11 |
12 | public ArticleMemento getMemento() {
13 | ArticleMemento articleMemento = ARTICLE_MEMENTO_STACK.pop();
14 | return articleMemento;
15 | }
16 |
17 | public void addMemento(ArticleMemento articleMemento) {
18 | ARTICLE_MEMENTO_STACK.push(articleMemento);
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/memento/TestMemento.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.memento;
2 |
3 | /**
4 | * 备忘录模式
5 | * 定义:保存某个对象的某个状态,以便于在适当的时候恢复对象
6 | * 特征:"后悔药"
7 | * 类型:行为型
8 | *
9 | * 适用场景:
10 | * 1.保存和恢复数据相关业务场景
11 | * 2.后悔的时候,即想恢复到之前的状态
12 | * 优点:
13 | * 1.为用户提供了一种可恢复的机制
14 | * 2.存档信息的封装
15 | * 缺点:
16 | * 1.资源占用
17 | */
18 | public class TestMemento {
19 |
20 | /**
21 | * 学习的时候会记录自己的思路,然后会记下来,如果想修改,可以恢复到之前保存的状态
22 | */
23 | public static void test() {
24 | ArticleMementoManager articleMementoManager = new ArticleMementoManager();
25 |
26 | Article article = new Article("如影随行的设计模式A", "手记内容A", "手记图片A");
27 | ArticleMemento articleMemento = article.saveToMemento();
28 | articleMementoManager.addMemento(articleMemento);
29 | System.out.println("标题:" + article.getTitle() + " 内容:" + article.getContent() + " 图片:" + article.getImgs() + " 暂存成功");
30 | System.out.println("手记完整信息:" + article);
31 |
32 |
33 |
34 | System.out.println("修改手记start");
35 |
36 | article.setTitle("如影随行的设计模式B");
37 | article.setContent("手记内容B");
38 | article.setImgs("手记图片B");
39 |
40 | System.out.println("修改手记end");
41 |
42 | System.out.println("手记完整信息:" + article);
43 |
44 | articleMemento = article.saveToMemento();
45 | articleMementoManager.addMemento(articleMemento);
46 |
47 |
48 | article.setTitle("如影随行的设计模式C");
49 | article.setContent("手记内容C");
50 | article.setImgs("手记图片C");
51 |
52 | System.out.println("暂存回退start");
53 |
54 | System.out.println("回退出栈1次");
55 | articleMemento = articleMementoManager.getMemento();
56 | article.undoFromMemento(articleMemento);
57 |
58 | System.out.println("回退出栈2次");
59 | articleMemento = articleMementoManager.getMemento();
60 | article.undoFromMemento(articleMemento);
61 |
62 |
63 | System.out.println("暂存回退end");
64 | System.out.println("手记完整信息:" + article);
65 |
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/observer/GirlFriendObserver.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.observer;
2 |
3 |
4 | /**
5 | *
6 | * 观察者的一个子类 实现类
7 | *
8 | * 我的其中一个女朋友
9 | */
10 | public class GirlFriendObserver implements Observer {
11 |
12 | private String name;
13 |
14 | public String getName() {
15 | return name;
16 | }
17 |
18 | public GirlFriendObserver(String name) {
19 | super();
20 | this.name = name;
21 | }
22 |
23 | @Override
24 | public void update(String state) {
25 |
26 | System.out.println(name + "接到最新消息,男朋友最新状态:" + state);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/observer/MessageObservable.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.observer;
2 |
3 | /**
4 | *
5 | * 被观察者的 子类
6 | */
7 | public class MessageObservable extends Observable {
8 |
9 | public void change(String state) {
10 |
11 | notyfyObservers(state);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/observer/Observable.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.observer;
2 |
3 | import java.util.ArrayList;
4 |
5 | /**
6 | *
7 | * 被观察者
8 | * 我自己
9 | */
10 | public abstract class Observable {
11 |
12 | private ArrayList observers = new ArrayList();
13 |
14 | /**
15 | * 添加一个观察者
16 | */
17 | public void attach(Observer observer) {
18 | observers.add(observer);
19 | System.out.println("我新交了一个女朋友");
20 | }
21 |
22 | /**
23 | *去掉一个观察者
24 | */
25 | public void dettch(Observer observer) {
26 | observers.remove(observer);
27 | System.out.println("我和她分手了");
28 | }
29 |
30 | /**
31 | * 通知观察者(就是通知我的女朋友们)
32 | */
33 | public void notyfyObservers(String state) {
34 | for (Observer observer : observers) {
35 |
36 | observer.update(state);
37 |
38 | }
39 |
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/observer/Observer.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.observer;
2 |
3 |
4 | /**
5 | *
6 | *观察者
7 | *
8 | *女朋友们 是观察者
9 | */
10 | public interface Observer {
11 |
12 | void update(String state);
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/observer/ObserverTest.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.observer;
2 |
3 | /**
4 | * 观察者模式
5 | * 定义:定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有观察者都会收到通知并更新
6 | * 类型:行为型
7 | *
8 | * 适用场景:
9 | * 1.关联行为场景,建立一套触发机制
10 | *
11 | * 优点:
12 | * 1.观察者和被观察者之间建立一个抽象的耦合
13 | * 2.观察者模式支持广播通信
14 | * 缺点:
15 | * 1.观察者之间有过多的细节依赖,提高时间消耗和程序复杂度
16 | * 2.使用要得当,要避免循环调用
17 | */
18 | public class ObserverTest {
19 |
20 | /**
21 | *
22 | */
23 | public static void test() {
24 | //创建2个观察者
25 | Observer fanbingbing = new GirlFriendObserver("范冰冰");
26 | Observer yangmi = new GirlFriendObserver("杨幂");
27 |
28 | //创建被观察者
29 | MessageObservable messageSubject = new MessageObservable();
30 |
31 | //被观察者 添加 观察者 到集合中
32 | messageSubject.attach(fanbingbing);
33 | messageSubject.attach(yangmi);
34 | //被观察者 通知 观察者,我都干了什么
35 | messageSubject.change("我在大保健");
36 |
37 | messageSubject.dettch(yangmi);
38 | messageSubject.notyfyObservers("泡吧");
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/state/CourseVideoContext.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.state;
2 |
3 | /**
4 | * 课程视频内容
5 | */
6 | public class CourseVideoContext {
7 |
8 | private CourseVideoState courseVideoState;
9 | public final static PlayState PLAY_STATE = new PlayState();
10 | public final static StopState STOP_STATE = new StopState();
11 | public final static PauseState PAUSE_STATE = new PauseState();
12 | public final static SpeedState SPEED_STATE = new SpeedState();
13 |
14 | public CourseVideoState getCourseVideoState() {
15 | return courseVideoState;
16 | }
17 |
18 | public void setCourseVideoState(CourseVideoState courseVideoState) {
19 | this.courseVideoState = courseVideoState;
20 | this.courseVideoState.setCourseVideoContext(this);
21 | }
22 | public void play(){
23 | this.courseVideoState.play();
24 | }
25 |
26 | public void speed(){
27 | this.courseVideoState.speed();
28 | }
29 |
30 | public void stop(){
31 | this.courseVideoState.stop();
32 | }
33 |
34 | public void pause(){
35 | this.courseVideoState.pause();
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/state/CourseVideoState.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.state;
2 |
3 | /**
4 | * 课程视频状态 抽象类
5 | */
6 | public abstract class CourseVideoState {
7 | protected CourseVideoContext courseVideoContext;
8 |
9 | public void setCourseVideoContext(CourseVideoContext courseVideoContext) {
10 | this.courseVideoContext = courseVideoContext;
11 | }
12 |
13 | public abstract void play();
14 | public abstract void speed();
15 | public abstract void pause();
16 | public abstract void stop();
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/state/PauseState.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.state;
2 |
3 | /**
4 | * 暂停状态
5 | */
6 | public class PauseState extends CourseVideoState {
7 |
8 | @Override
9 | public void play() {
10 | super.courseVideoContext.setCourseVideoState(CourseVideoContext.PLAY_STATE);
11 | }
12 |
13 | @Override
14 | public void speed() {
15 | super.courseVideoContext.setCourseVideoState(CourseVideoContext.SPEED_STATE);
16 | }
17 |
18 | @Override
19 | public void pause() {
20 | System.out.println("暂停播放课程视频状态");
21 | }
22 |
23 | @Override
24 | public void stop() {
25 | super.courseVideoContext.setCourseVideoState(CourseVideoContext.STOP_STATE);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/state/PlayState.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.state;
2 |
3 | /**
4 | * 播放状态
5 | */
6 | public class PlayState extends CourseVideoState {
7 |
8 | @Override
9 | public void play() {
10 | System.out.println("正常播放课程视频状态");
11 | }
12 |
13 | @Override
14 | public void speed() {
15 | super.courseVideoContext.setCourseVideoState(CourseVideoContext.SPEED_STATE);
16 | }
17 |
18 | @Override
19 | public void pause() {
20 | super.courseVideoContext.setCourseVideoState(CourseVideoContext.PAUSE_STATE);
21 | }
22 |
23 | @Override
24 | public void stop() {
25 | super.courseVideoContext.setCourseVideoState(CourseVideoContext.STOP_STATE);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/state/SpeedState.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.state;
2 |
3 | /**
4 | * 快进状态
5 | */
6 | public class SpeedState extends CourseVideoState {
7 | @Override
8 | public void play() {
9 | super.courseVideoContext.setCourseVideoState(CourseVideoContext.PLAY_STATE);
10 | }
11 |
12 | @Override
13 | public void speed() {
14 | System.out.println("快进播放课程视频状态");
15 | }
16 |
17 | @Override
18 | public void pause() {
19 | super.courseVideoContext.setCourseVideoState(CourseVideoContext.PAUSE_STATE);
20 | }
21 |
22 | @Override
23 | public void stop() {
24 | super.courseVideoContext.setCourseVideoState(CourseVideoContext.STOP_STATE);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/state/StopState.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.state;
2 |
3 | /**
4 | * 暂停状态
5 | */
6 | public class StopState extends CourseVideoState {
7 | @Override
8 | public void play() {
9 | super.courseVideoContext.setCourseVideoState(CourseVideoContext.PLAY_STATE);
10 | }
11 |
12 | @Override
13 | public void speed() {
14 | System.out.println("ERROR 停止状态不能快进!!");
15 | }
16 |
17 | @Override
18 | public void pause() {
19 | System.out.println("ERROR 停止状态不能暂停!!");
20 | }
21 |
22 | @Override
23 | public void stop() {
24 | System.out.println("停止播放课程视频状态");
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/state/TestState.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.state;
2 |
3 | /**
4 | * 状态模式
5 | */
6 | public class TestState {
7 |
8 | /**
9 | * 播放一个课程,有多种状态,播放,暂停,快进,停止
10 | */
11 | public static void test() {
12 | CourseVideoContext courseVideoContext = new CourseVideoContext();
13 | courseVideoContext.setCourseVideoState(new PlayState());
14 |
15 | System.out.println("当前状态:"+courseVideoContext.getCourseVideoState().getClass().getSimpleName());
16 | courseVideoContext.pause();
17 |
18 | System.out.println("当前状态:"+courseVideoContext.getCourseVideoState().getClass().getSimpleName());
19 | courseVideoContext.speed();
20 |
21 | System.out.println("当前状态:"+courseVideoContext.getCourseVideoState().getClass().getSimpleName());
22 | courseVideoContext.stop();
23 |
24 | System.out.println("当前状态:"+courseVideoContext.getCourseVideoState().getClass().getSimpleName());
25 | courseVideoContext.speed();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/strategy/StrategyTest.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.strategy;
2 |
3 | import com.yadong.pattern.behavioral.strategy.duck.BaseDuck;
4 | import com.yadong.pattern.behavioral.strategy.duck.BeiJingDuck;
5 | import com.yadong.pattern.behavioral.strategy.duck.GreenHeadDuck;
6 |
7 | /**
8 | * 策略模式
9 | * 定义:定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户
10 | * 类型:行为型
11 | *
12 | * 适用场景:
13 | * 1.系统有很多类,而它们的区别仅仅在于它们的行为不同
14 | * 2.一个系统需要动态的在几种算法中选择一种
15 | * 优点:
16 | * 1.开闭原则
17 | * 2.避免使用多重条件转移语句
18 | * 3.提高算法的保密性和安全性
19 | * 缺点:
20 | * 1.客户端必须知道所有的策略类,并自行决定使用哪一个策略类
21 | * 2.产生很多策略类
22 | *
23 | */
24 | public class StrategyTest {
25 |
26 | /**
27 | *
28 | * 分别封装行为接口,实现算法族,父类中放行为接口对象,在子类里具体设定行为对象
29 | * 原则:分离变化部分,封装接口,基于接口编程各种功能.
30 | * 此模式让行为算法的变化独立于算法的使用者
31 | *
32 | * 鸭子项目中,飞行或者叫声等行为是变化的(能飞和不能飞),这个需要抽象成接口,然后放在鸭子的父类中,让子类鸭子去实现
33 | */
34 | public static void test() {
35 | BaseDuck beiJingDuck = new BeiJingDuck();
36 | BaseDuck greenHeadDuck = new GreenHeadDuck();
37 | beiJingDuck.display();
38 | greenHeadDuck.fly();
39 | beiJingDuck.display();
40 | greenHeadDuck.fly();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/strategy/behaviour/FlyBehaviour.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.strategy.behaviour;
2 |
3 |
4 | /**
5 | * 飞行的行为接口
6 | */
7 | public interface FlyBehaviour {
8 | void fly();
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/strategy/behaviour/FlyImp.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.strategy.behaviour;
2 |
3 | /**
4 | * 能够飞行的行为接口实现类
5 | */
6 | public class FlyImp implements FlyBehaviour {
7 |
8 | @Override
9 | public void fly() {
10 | System.out.println("能够飞行~~~");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/strategy/behaviour/FlyNoWayImp.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.strategy.behaviour;
2 |
3 | /**
4 | * 不能够飞行的行为接口实现类
5 | */
6 | public class FlyNoWayImp implements FlyBehaviour {
7 |
8 | @Override
9 | public void fly() {
10 | System.out.println("不能飞,飞不起来~~~");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/strategy/duck/BaseDuck.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.strategy.duck;
2 |
3 | import com.yadong.pattern.behavioral.strategy.behaviour.FlyBehaviour;
4 | import com.yadong.pattern.behavioral.strategy.behaviour.FlyImp;
5 | import com.yadong.pattern.behavioral.strategy.behaviour.FlyNoWayImp;
6 |
7 | /**
8 | * 父类 Duck
9 | */
10 | public abstract class BaseDuck {
11 |
12 | //这个是接口,让子类去实现这个接口
13 | FlyBehaviour mFlyBehaviour;
14 |
15 | public void fly() {
16 | mFlyBehaviour.fly();
17 | }
18 |
19 |
20 | public abstract void display();
21 |
22 |
23 | /**
24 | * 设置可以飞行的行为接口实现类
25 | */
26 | public void setFlyBehaviour(FlyImp flyImp){
27 | this.mFlyBehaviour=flyImp;
28 | }
29 |
30 | /**
31 | * 设置不可以飞行的行为接口实现类
32 | */
33 | public void setFlyNoWayBehaviour(FlyNoWayImp flyNoWayBehaviour){
34 | this.mFlyBehaviour=flyNoWayBehaviour;
35 |
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/strategy/duck/BeiJingDuck.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.strategy.duck;
2 |
3 | import com.yadong.pattern.behavioral.strategy.behaviour.FlyNoWayImp;
4 |
5 | /**
6 | * 北京烤鸭,飞不起来
7 | * 构造方法中,实现了飞不起来的行为接口实现类对象
8 | */
9 | public class BeiJingDuck extends BaseDuck {
10 |
11 | public BeiJingDuck() {
12 | mFlyBehaviour = new FlyNoWayImp();
13 | }
14 |
15 | @Override
16 | public void display() {
17 | System.out.println(BeiJingDuck.class.getName());
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/strategy/duck/GreenHeadDuck.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.strategy.duck;
2 |
3 | import com.yadong.pattern.behavioral.strategy.behaviour.FlyImp;
4 |
5 | /**
6 | * 绿头鸭,能够飞行
7 | * 在构造方法中实现了飞行行为的接口
8 | */
9 | public class GreenHeadDuck extends BaseDuck {
10 |
11 |
12 | public GreenHeadDuck() {
13 | this.mFlyBehaviour = new FlyImp();
14 | }
15 |
16 | @Override
17 | public void display() {
18 | System.out.println(GreenHeadDuck.class.getName());
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/template_method/ACourse.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.template_method;
2 |
3 | /**
4 | * 课程
5 | */
6 | public abstract class ACourse {
7 |
8 | //模板方法 制作课程
9 | protected final void makeCourse(){
10 | this.makePPT();
11 | this.makeVideo();
12 | if(needWriteArticle()){
13 | this.writeArticle();
14 | }
15 | this.packageCourse();
16 | }
17 |
18 | final void makePPT(){
19 | System.out.println("制作PPT");
20 | }
21 | final void makeVideo(){
22 | System.out.println("制作视频");
23 | }
24 | final void writeArticle(){
25 | System.out.println("编写手记");
26 | }
27 | //钩子方法
28 | protected boolean needWriteArticle(){
29 | return false;
30 | }
31 |
32 | //包装课程
33 | abstract void packageCourse();
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/template_method/DesignPatternCourse.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.template_method;
2 |
3 | /**
4 | * 设计模式课程
5 | */
6 | public class DesignPatternCourse extends ACourse {
7 |
8 | @Override
9 | void packageCourse() {
10 | System.out.println("提供课程Java源代码");
11 | }
12 |
13 | @Override
14 | protected boolean needWriteArticle() {
15 | return true;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/template_method/FECourse.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.template_method;
2 |
3 | /**
4 | * 前端课程
5 | */
6 | public class FECourse extends ACourse {
7 |
8 | private boolean needWriteArticleFlag = false;
9 |
10 | @Override
11 | void packageCourse() {
12 | System.out.println("提供课程的前端代码");
13 | System.out.println("提供课程的图片等多媒体素材");
14 | }
15 |
16 | public FECourse(boolean needWriteArticleFlag) {
17 | this.needWriteArticleFlag = needWriteArticleFlag;
18 | }
19 |
20 | @Override
21 | protected boolean needWriteArticle() {
22 | return this.needWriteArticleFlag;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/template_method/TestTemplateMethod.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.template_method;
2 |
3 |
4 | /**
5 | * 模板方法
6 | * 定义:定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现
7 | * 特征:模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤
8 | * 类型:行为型
9 | *
10 | * 适用场景:
11 | * 1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现
12 | * 2.各子类中公共的行为被提取出来并集中到一个公共父类中,从而避免代码重复
13 | * 优点:
14 | * 1.提高复用性
15 | * 2.提高扩展性
16 | * 3.符合开闭原则
17 | * 缺点:
18 | * 1.类数目的增加
19 | * 2.增加了系统实现的复杂度
20 | * 3.继承关系自身缺点,如果父类添加新的抽象方法,所有的子类都要改一遍
21 | * 扩展:
22 | * 1.钩子方法
23 | */
24 | public class TestTemplateMethod {
25 |
26 |
27 | /**
28 | * 场景:录制视频都需要编写ppt,制作视频和写手记,然后用这个模板制作不同的课程
29 | */
30 | public static void test(){
31 | System.out.println("后端设计模式课程start---");
32 | ACourse designPatternCourse = new DesignPatternCourse();
33 | designPatternCourse.makeCourse();
34 | System.out.println("后端设计模式课程end---");
35 |
36 |
37 | System.out.println("前端课程start---");
38 | ACourse feCourse = new FECourse(false);
39 | feCourse.makeCourse();
40 | System.out.println("前端课程end---");
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/visitor/CodingCourse.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.visitor;
2 |
3 | /**
4 | * 付费课程
5 | */
6 | public class CodingCourse extends Course {
7 | private int price;
8 |
9 | public int getPrice() {
10 | return price;
11 | }
12 |
13 | public void setPrice(int price) {
14 | this.price = price;
15 | }
16 |
17 | @Override
18 | public void accept(IVisitor visitor) {
19 | visitor.visit(this);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/visitor/Course.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.visitor;
2 |
3 | /**
4 | *课程
5 | */
6 | public abstract class Course {
7 | private String name;
8 |
9 |
10 | public String getName() {
11 | return name;
12 | }
13 |
14 | public void setName(String name) {
15 | this.name = name;
16 | }
17 |
18 |
19 | //是否接受访问
20 | public abstract void accept(IVisitor visitor);
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/visitor/FreeCourse.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.visitor;
2 |
3 | /**
4 | * 免费课程
5 | */
6 | public class FreeCourse extends Course {
7 |
8 | @Override
9 | public void accept(IVisitor visitor) {
10 | visitor.visit(this);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/visitor/IVisitor.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.visitor;
2 |
3 | /**
4 | *Visitor 接口
5 | */
6 | public interface IVisitor {
7 |
8 | //访问免费课程
9 | void visit(FreeCourse freeCourse);
10 |
11 | //访问付费课程
12 | void visit(CodingCourse codingCourse);
13 |
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/visitor/TestVisitor.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.visitor;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 访问者模式
8 | * 定义:封装作用于某数据结构(比如List,Set,Map等)中的个元素的操作
9 | * 特征:可以在不改变个元素的类的前提下,定义作用于这些元素的操作
10 | * 类型:行为型
11 | *
12 | * 适用场景:
13 | * 1.一个数据结构如(List/Set/Map等)包含很多类型对象
14 | * 2.数据结构与数据操作分类
15 | * 优点:
16 | * 1.增加新的操作很容易,就是增加一个新的访问者
17 | * 缺点:
18 | * 1.增加新的数据结构困难
19 | * 2.具体元素变更比较麻烦
20 | *
21 | * 比较低频的设计模式
22 | */
23 | public class TestVisitor {
24 |
25 | /**
26 | * 网站上有免费课程和实战课程
27 | */
28 | public static void test() {
29 | List courseList = new ArrayList<>();
30 |
31 | //免费课程
32 | FreeCourse freeCourse = new FreeCourse();
33 | freeCourse.setName("Android基础");
34 |
35 | //付费课程
36 | CodingCourse codingCourse = new CodingCourse();
37 | codingCourse.setName("Java设计模式精讲");
38 | codingCourse.setPrice(299);
39 |
40 | courseList.add(freeCourse);
41 | courseList.add(codingCourse);
42 |
43 | for (Course course : courseList) {
44 | course.accept(new Visitor());
45 | }
46 |
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/behavioral/visitor/Visitor.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.behavioral.visitor;
2 |
3 | /**
4 | *
5 | */
6 | public class Visitor implements IVisitor {
7 |
8 | //访问免费课程,打印所有免费课程名称
9 | @Override
10 | public void visit(FreeCourse freeCourse) {
11 | System.out.println("免费课程:"+freeCourse.getName());
12 | }
13 |
14 | //访问付费课程,打印所有实战课程名称及价格
15 | @Override
16 | public void visit(CodingCourse codingCourse) {
17 | System.out.println("付费课程:"+codingCourse.getName()+" 价格:"+codingCourse.getPrice()+"元");
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/builder/Person.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.builder;
2 |
3 | /**
4 | * 设计模型讲究的是一个平衡和业务模型的一个匹配。
5 | * 自己没事练手的builder模式
6 | * 我们要创建一个Person对象,一个Person对象需要很多参数,这属于一个复杂对象的创建。
7 | */
8 | public class Person {
9 |
10 | private String mName;
11 | private int mAge;
12 | private String mKungFu;
13 |
14 | /**
15 | * 步骤3:Builder属性赋值给Person
16 | * 构造函数私有化
17 | * 只让下面的静态方法builder()能够创建对象
18 | */
19 | private Person(Builder builder) {
20 | mName = builder.getName();
21 | mAge = builder.getAge();
22 | mKungFu = builder.getKungFu();
23 | }
24 |
25 | /**
26 | * 步骤4:创建具体的建造者
27 | * 构建Person对象的构建器,就是通过Builder这个对象去构建Person对象
28 | */
29 | public static Builder builder() {
30 | return new Builder();
31 | }
32 |
33 | /**
34 | * 步骤1:定义大侠的过程(Builder):定义大侠的名字,年龄和武功
35 | */
36 | public static class Builder {
37 |
38 | private String mName;
39 | private int mAge;
40 | private String mKungFu;
41 |
42 | public Builder setName(String name) {
43 | this.mName = name;
44 | return this;
45 | }
46 |
47 | public Builder setAge(int age) {
48 | this.mAge = age;
49 | return this;
50 | }
51 |
52 | public Builder setKungFu(String kungfu) {
53 | this.mKungFu = kungfu;
54 | return this;
55 | }
56 |
57 | public String getName() {
58 | return mName;
59 | }
60 |
61 | public int getAge() {
62 | return mAge;
63 | }
64 |
65 | public String getKungFu() {
66 | return mKungFu;
67 | }
68 |
69 | /**
70 | * 步骤2:构建真正的Person对象并返回
71 | */
72 | public Person build() {
73 | return new Person(this);
74 | }
75 | }
76 |
77 | @Override
78 | public String toString() {
79 | return "Person{" +
80 | "mName='" + mName + '\'' +
81 | ", mAge=" + mAge +
82 | ", mKungFu='" + mKungFu + '\'' +
83 | '}';
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/builder/TestBuilder.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.builder;
2 |
3 | /**
4 | * 建造者模式
5 | * 定义:将一个复杂的对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示
6 | * 特征:用户只需指定需要建造的类型就可以得到它们,建造过程和细节不需要知道
7 | * 类型:创建型
8 | * 适用场景:
9 | * 1.如果一个对象有非常复杂的内部结构(很多属性字段)
10 | * 2.想把复杂对象的创建和使用分离
11 | * 优点:
12 | * 1.封装性好,创建和使用分离。
13 | * 2.扩展性好,建造类之间独立,一定程度上解耦
14 | * 缺点:
15 | * 1.产生多余的Builder对象。
16 | * 2.产品内部发生变化,建造者都要修改,成本比较大
17 | *
18 | * 个人理解
19 | * 1.简单来说,建造者模式就是如何一步一步构建一个包含多个组件的对象,相同的构建过程可以创建不同的产品.
20 | * 适用于流程固定,但是顺序不一定固定的。
21 | * 2.对象的建造过程和细节不需要知道,但是我们也可以创建出来复杂的对象。
22 | * 3.举个例子,做一盘菜,做菜的构建过程相对复杂,有的人喜欢先放盐,有的人喜欢后放盐,但是放盐这个组件是一定要加的。
23 | */
24 | public class TestBuilder {
25 |
26 | /**
27 | * 步骤5:客户端调用-创建武林隐士高手
28 | * 背景:打游戏想创建一个武林大侠
29 | * 目的:希望通过建造者模式去创建
30 | */
31 | public static void test() {
32 | Person person = Person.builder()
33 | .setName("风清扬")
34 | .setAge(99)
35 | .setKungFu("独孤九剑")
36 | .build();
37 | System.out.println(person.toString());
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_abstract/TestFactoryAbstract.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_abstract;
2 |
3 | import com.yadong.pattern.creational.factory_abstract.base.BaseCourseFactory;
4 | import com.yadong.pattern.creational.factory_abstract.java_course.JavaCourseFactory;
5 | import com.yadong.pattern.creational.factory_abstract.python_course.PythonCourseFactory;
6 |
7 | /**
8 | * 抽象工厂
9 | * 定义:提供了一个创建一系列相关或相互依赖对象的接口
10 | * 特征:无须指定他们具体的类
11 | * 类型:创建型
12 | * 适用场景:
13 | * 1.客户端(应用层)不依赖于产品实例如何被创建,实现等细节
14 | * 2.强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码
15 | * 3.提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
16 | * 优点:
17 | * 1.具体产品在应用层代码隔离,无需关心创建细节
18 | * 2.将一个系列的产品族统一到一起创建
19 | * 缺点:
20 | * 1.规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
21 | * 2.增加了系统的抽象性和理解难度
22 | */
23 | public class TestFactoryAbstract {
24 |
25 |
26 | /**
27 | * 步骤5:客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例
28 | * 背景:想分享,然后通过生产Java视频和Python视频的方式进行传播
29 | * 目的:希望使用工厂方法模式实现这2个产品的生产
30 | */
31 | public static void test() {
32 | //通过JavaCourseFactory去创建javaVideo和JavaNote
33 | BaseCourseFactory courseFactory = new JavaCourseFactory();//创建Java课程工厂
34 | courseFactory.getVideo().produce();//通过工厂类得到JavaVideo对象并进行创建
35 | courseFactory.getNote().produce();//通过工厂类得到JavaNote对象并进行创建
36 |
37 |
38 | //通过PythonCourseFactory去创建pythonVideo和PythonNote
39 | PythonCourseFactory pythonCourseFactory = new PythonCourseFactory();//创建Python课程工厂
40 | pythonCourseFactory.getVideo().produce();//通过工厂类得到PythonVideo对象并进行创建
41 | pythonCourseFactory.getNote().produce();//通过工厂类得到PythonNote对象并进行创建
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_abstract/base/BaseCourseFactory.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_abstract.base;
2 |
3 |
4 | /**
5 | * 步骤1:创建抽象工厂接口,定义具体工厂的公共接口
6 | * 抽象工厂接口
7 | */
8 | public interface BaseCourseFactory {
9 | BaseVideo getVideo();
10 |
11 | BaseNote getNote();
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_abstract/base/BaseNote.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_abstract.base;
2 |
3 | /**
4 | * 步骤2:创建抽象产品族类,定义具体产品的公共接口
5 | */
6 | public abstract class BaseNote {
7 | public abstract void produce();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_abstract/base/BaseVideo.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_abstract.base;
2 |
3 | /**
4 | * 步骤2:创建抽象产品族类,定义具体产品的公共接口
5 | */
6 | public abstract class BaseVideo {
7 | public abstract void produce();
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_abstract/java_course/JavaCourseFactory.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_abstract.java_course;
2 |
3 | import com.yadong.pattern.creational.factory_abstract.base.BaseNote;
4 | import com.yadong.pattern.creational.factory_abstract.base.BaseVideo;
5 | import com.yadong.pattern.creational.factory_abstract.base.BaseCourseFactory;
6 |
7 | /**
8 | * 步骤4:创建具体工厂类(实现抽象工厂接口),定义创建对应具体产品实例的方法
9 | * 具体的Java课程工厂,专门生产JavaVideo和JavaNotes
10 | */
11 | public class JavaCourseFactory implements BaseCourseFactory {
12 |
13 | @Override
14 | public BaseVideo getVideo() {
15 | return new JavaVideo();
16 | }
17 |
18 | @Override
19 | public BaseNote getNote() {
20 | return new JavaNote();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_abstract/java_course/JavaNote.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_abstract.java_course;
2 |
3 | import com.yadong.pattern.creational.factory_abstract.base.BaseNote;
4 |
5 | /**
6 | * 步骤3:创建具体产品类(继承抽象产品类)定义生产的具体产品
7 | * Java笔记对象
8 | */
9 | public class JavaNote extends BaseNote {
10 | @Override
11 | public void produce() {
12 | System.out.println("编写Java课程笔记");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_abstract/java_course/JavaVideo.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_abstract.java_course;
2 |
3 | import com.yadong.pattern.creational.factory_abstract.base.BaseVideo;
4 |
5 | /**
6 | * 步骤3:创建具体产品类(继承抽象产品类),定义生产的具体产品
7 | * Java录像对象
8 | */
9 | public class JavaVideo extends BaseVideo {
10 | @Override
11 | public void produce() {
12 | System.out.println("生产Java课程视频");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_abstract/python_course/PythonCourseFactory.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_abstract.python_course;
2 |
3 | import com.yadong.pattern.creational.factory_abstract.base.BaseNote;
4 | import com.yadong.pattern.creational.factory_abstract.base.BaseVideo;
5 | import com.yadong.pattern.creational.factory_abstract.base.BaseCourseFactory;
6 |
7 | /**
8 | * 步骤4:创建具体工厂类(实现抽象工厂接口),定义创建对应具体产品实例的方法
9 | * 具体的Python课程工厂,专门生产PythonVideo和PythonNotes
10 | */
11 | public class PythonCourseFactory implements BaseCourseFactory {
12 |
13 | @Override
14 | public BaseVideo getVideo() {
15 | return new PythonVideo();
16 | }
17 |
18 | @Override
19 | public BaseNote getNote() {
20 | return new PythonNote();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_abstract/python_course/PythonNote.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_abstract.python_course;
2 |
3 | import com.yadong.pattern.creational.factory_abstract.base.BaseNote;
4 |
5 | /**
6 | * 步骤3:创建具体产品类(继承抽象产品类),定义生产的具体产品
7 | * Python笔记对象
8 | */
9 | public class PythonNote extends BaseNote {
10 | @Override
11 | public void produce() {
12 | System.out.println("编写Python课程笔记");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_abstract/python_course/PythonVideo.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_abstract.python_course;
2 |
3 | import com.yadong.pattern.creational.factory_abstract.base.BaseVideo;
4 |
5 | /**
6 | * 步骤3:创建具体产品类(继承抽象产品类)定义生产的具体产品
7 | * Python录像对象
8 | */
9 | public class PythonVideo extends BaseVideo {
10 | @Override
11 | public void produce() {
12 | System.out.println("生产Python课程视频");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_method/TestFactoryMethod.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_method;
2 |
3 | import com.yadong.pattern.creational.factory_method.base.VideoProduct;
4 | import com.yadong.pattern.creational.factory_method.java_video.JavaVideoFactory;
5 | import com.yadong.pattern.creational.factory_method.python_video.PythonVideoFactory;
6 |
7 | /**
8 | * 工厂方法
9 | * 定义:定义一个创建对象的接口,但是让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行
10 | * 类型:创建型
11 | * 适用场景:
12 | * 1.创建对象需要大量重复的代码
13 | * 2.客户端(应用层)不依赖于产品类实例如何被创建,实现等细节
14 | * 3.一个类通过其子类来指定创建哪个对象
15 | * 4.创建对象的过程推迟到子类中来
16 | * 优点:
17 | * 1.用户只需要关心所需产品对应的工厂,无需关心创建细节
18 | * 2.加入新产品符合开闭原则,提高可扩展性
19 | * 缺点:
20 | * 1.类的个数容易过多,增加复杂度
21 | * 2.增加了系统的抽象性和理解难度
22 | *
23 | * 个人理解:
24 | * 我们只需要关心产品对应的工厂,而不需要关心其细节.然后想创建什么类就找对应的工厂.
25 | * 然后类的具体实例化延迟到子类工厂类中去进行
26 | */
27 | public class TestFactoryMethod {
28 |
29 |
30 | /**
31 | * 背景:想分享,然后通过生产Java视频和Python视频的方式进行传播
32 | * 目的:希望使用工厂方法模式实现这2个产品的生产
33 | * 步骤5:外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例
34 | */
35 | public static void test() {
36 | //创建JavaVideo,对应的工厂创建对应的对象
37 | JavaVideoFactory factory = new JavaVideoFactory();
38 | VideoProduct video = factory.getVideo();
39 | video.produce();
40 |
41 | //创建PythonVideo,对应的工厂创建对应的对象
42 | PythonVideoFactory pythonVideoFactory = new PythonVideoFactory();
43 | VideoProduct pythonVideo = pythonVideoFactory.getVideo();
44 | pythonVideo.produce();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_method/base/Factory.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_method.base;
2 |
3 |
4 | /**
5 | * 步骤1:创建抽象工厂类,定义具体工厂的公共接口
6 | */
7 | public interface Factory {
8 | VideoProduct getVideo();
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_method/base/VideoProduct.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_method.base;
2 |
3 | /**
4 | * 步骤2:创建抽象产品类,定义具体产品的公共接口;
5 | */
6 | public abstract class VideoProduct {
7 | public abstract void produce();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_method/java_video/JavaVideo.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_method.java_video;
2 |
3 | import com.yadong.pattern.creational.factory_method.base.VideoProduct;
4 |
5 | /**
6 | * 步骤3:创建具体产品类(继承抽象产品类),定义生产的具体产品;
7 | * JavaVideo是继承BaseVideo的
8 | */
9 | public class JavaVideo extends VideoProduct {
10 | @Override
11 | public void produce() {
12 | System.out.println("录制Java课程视频");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_method/java_video/JavaVideoFactory.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_method.java_video;
2 |
3 | import com.yadong.pattern.creational.factory_method.base.VideoProduct;
4 | import com.yadong.pattern.creational.factory_method.base.Factory;
5 |
6 | /**
7 | * 步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
8 | * JavaVideo的工厂类实现BaseVideoFactory接口,延迟到子类中来创建具体的对象
9 | * 总而言之就是,什么工厂创建什么对象,JavaVideoFactory工厂就创建JavaVideo
10 | */
11 | public class JavaVideoFactory implements Factory {
12 |
13 | /**
14 | * 工厂方法
15 | */
16 | @Override
17 | public VideoProduct getVideo() {
18 | return new JavaVideo();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_method/python_video/PythonVideo.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_method.python_video;
2 |
3 | import com.yadong.pattern.creational.factory_method.base.VideoProduct;
4 |
5 | /**
6 | * 步骤3:创建具体产品类(继承抽象产品类),定义生产的具体产品;
7 | * PythonVideo是继承BaseVideo的
8 | */
9 | public class PythonVideo extends VideoProduct {
10 | @Override
11 | public void produce() {
12 | System.out.println("录制Python课程视频");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_method/python_video/PythonVideoFactory.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_method.python_video;
2 |
3 | import com.yadong.pattern.creational.factory_method.base.VideoProduct;
4 | import com.yadong.pattern.creational.factory_method.base.Factory;
5 |
6 | /**
7 | * 步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
8 | * PythonVideo的工厂类实现BaseVideoFactory接口,延迟到子类中来创建具体的对象
9 | * 总而言之就是,什么工厂创建什么对象,PythonVideoFactory工厂就创建PythonVideo
10 | */
11 | public class PythonVideoFactory implements Factory {
12 |
13 | /**
14 | * 工厂方法
15 | */
16 | @Override
17 | public VideoProduct getVideo() {
18 | return new PythonVideo();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_simple/BaseVideo.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_simple;
2 |
3 | /**
4 | * 步骤1.创建抽象产品类,定义具体产品的公共接口
5 | * 抽象类BaseVideo,让具体的子类去继承
6 | */
7 | public abstract class BaseVideo {
8 | public abstract void produce();
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_simple/JavaVideo.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_simple;
2 |
3 | /**
4 | * 步骤2.创建具体产品类(继承抽象产品类),定义生产的具体产品
5 | * JavaVideo,继承于BaseVideo
6 | */
7 | public class JavaVideo extends BaseVideo {
8 |
9 | @Override
10 | public void produce() {
11 | System.out.println("生产JavaVideo");
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_simple/PythonVideo.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_simple;
2 |
3 | /**
4 | * 步骤2.创建具体产品类(继承抽象产品类),定义生产的具体产品
5 | * PythonVideo,继承于BaseVideo
6 | */
7 | public class PythonVideo extends BaseVideo {
8 |
9 | @Override
10 | public void produce() {
11 | System.out.println("生产PythonVideo");
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_simple/TestFactorySimple.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_simple;
2 |
3 | /**
4 | * 简单工厂,它不属于GOF23种设计模式
5 | * 定义:由一个工厂对象决定创建出哪一种产品类的实例
6 | * 类型:创建型
7 | * 适用场景:
8 | * 1.工厂类负责创建的对象比较少
9 | * 2.客户端(应用层)只知道传入工厂类的参数,对于如何创建对象并不关心
10 | * 优点:
11 | * 1.只需要传入一个正确的参数,就可以获取你所需要的对象而无需知道其创建细节
12 | * 缺点:
13 | * 1.工厂类的职责相对过重,增加新的产品,需要修改工厂类的判断逻辑,违背开闭原则
14 | */
15 | public class TestFactorySimple {
16 |
17 | /**
18 | * 背景:想分享,然后通过生产Java视频和Python视频的方式进行传播
19 | * 目的:希望使用工厂方法模式实现这2个产品的生产
20 | * 步骤4. 创建工厂类对象,外界通过调用工厂类对象的方法,传入不同参数从而创建不同具体产品类的实例
21 | */
22 | public static void test() {
23 | VideoFactory videoFactory = new VideoFactory();
24 | //创建JavaVideo,根据类的Class字节码
25 | com.yadong.pattern.creational.factory_simple.BaseVideo javaVideo = videoFactory.getVideo(JavaVideo.class);
26 | javaVideo.produce();
27 |
28 | //创建PythonVideo,根据String字符串类型
29 | com.yadong.pattern.creational.factory_simple.BaseVideo pythonVideo = videoFactory.getVideo("python");
30 | pythonVideo.produce();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/factory_simple/VideoFactory.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.factory_simple;
2 |
3 | /**
4 | * 步骤3.创建工厂类,根据传入不同参数创建不同具体产品类的实例对象
5 | * VideoFactory,工厂类,根据类型去生产具体的对象
6 | */
7 | public class VideoFactory {
8 |
9 | /**
10 | * 根据Class字节码对象去得到对应的对象
11 | */
12 | public BaseVideo getVideo(Class c){
13 | BaseVideo video=null;
14 | try {
15 | video = (BaseVideo) Class.forName(c.getName()).newInstance();
16 | } catch (InstantiationException e) {
17 | e.printStackTrace();
18 | } catch (IllegalAccessException e) {
19 | e.printStackTrace();
20 | } catch (ClassNotFoundException e) {
21 | e.printStackTrace();
22 | }
23 | return video;
24 | }
25 |
26 | /**
27 | * 根据type类型去得到对应的对象
28 | */
29 | public BaseVideo getVideo(String type){
30 | if("java".equalsIgnoreCase(type)){
31 | return new JavaVideo();
32 | }else if("python".equalsIgnoreCase(type)){
33 | return new PythonVideo();
34 | }
35 | return null;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/prototype/TestPrototype.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.prototype;
2 |
3 | import com.yadong.pattern.creational.prototype.deep_clone.Pig;
4 | import com.yadong.pattern.creational.prototype.shallow_clone.Mail;
5 | import com.yadong.pattern.creational.prototype.shallow_clone.MailUtil;
6 |
7 | import java.util.Date;
8 | /**
9 | * 原型模式
10 | * 定义:指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
11 | * 特征:不需要知道任何创建的细节,不调用构造函数
12 | * 类型:创建型
13 | * 适用场景:
14 | * 1.类初始化消耗较多资源
15 | * 2.new产生的一个对象需要非常繁琐的过程(属性赋值,访问权限等)
16 | * 3.构造函数比较复杂
17 | * 4.循环体中生产大量对象
18 | * 优点:
19 | * 1.原型模式性能比直接new一个对象性能高
20 | * 2.简化创建过程
21 | * 缺点:
22 | * 1.必须配备克隆方法(这个模式的核心就是clone方法)
23 | * 2.对克隆复杂对象或对克隆出的对象进行复杂改造时,容易引入风险
24 | * 3.深拷贝,浅拷贝要运用得当
25 | * 扩展:
26 | * 1.深克隆
27 | * 2.浅克隆
28 | */
29 | public class TestPrototype {
30 |
31 |
32 | public static void test() throws CloneNotSupportedException {
33 | shallowClone();
34 | deepClone();
35 | }
36 |
37 | /**
38 | * 浅克隆
39 | */
40 | private static void shallowClone() throws CloneNotSupportedException {
41 | /**
42 | * 下面这个例子目的是:
43 | * 创建一个Mail对象,然后保存初始化的内容,然后一个for循环,发送10份出去
44 | */
45 | Mail mail = new Mail();
46 | mail.setContent("初始化模板");
47 | System.out.println("初始化mail:"+mail);
48 | for(int i = 0;i < 10;i++){
49 | //根据原始的Mai对象,去clone 一个全新的Mail对象,这个是用二进制的流的方式复制的,所以性能比较好
50 | //目前这个是浅拷贝
51 | Mail mailTemp = (Mail) mail.clone();//这个clone并没有调用构造器,只是调用了clone方法,但是对象是新的
52 |
53 | mailTemp.setName("姓名"+i);
54 | mailTemp.setEmailAddress("姓名"+i+"@163.com");
55 | mailTemp.setContent("恭喜您,你中奖了,500W!!!!");
56 |
57 | MailUtil.sendMail(mailTemp);//发送邮件
58 | System.out.println("克隆的mailTemp:"+mailTemp);
59 | }
60 | //假如现在的业务非常复杂,这个保存Mail对象需要放到最后面
61 | //保存原始的Mail对象
62 | MailUtil.saveOriginMailRecord(mail);
63 | }
64 |
65 | /**
66 | * 深克隆
67 | */
68 | private static void deepClone() throws CloneNotSupportedException {
69 | Date birthday = new Date(0L);
70 | Pig pig1 = new Pig("佩奇",birthday);
71 | Pig pig2 = (Pig) pig1.clone();//从pig1 clone出来pig2
72 |
73 | /**
74 | * 下面的打印pig1和pig2是两个不同的对象,这个没有问题
75 | * 但是,里面的Date类型的mBirthday生日对象,这个是同一个对象,这个克隆出来的Date引用的是用一个对象
76 | * 所以修改pig1的生日,pig2也会跟着改变(这就是需要注意的点),所以需要深克隆
77 | */
78 | System.out.println(pig1);
79 | System.out.println(pig2);
80 |
81 | //改变pig1的生日日期,目的只是修改pig1的生日,并没有打算修改pig2的生日
82 | pig1.getBirthday().setTime(666666666666L);
83 |
84 |
85 | /**
86 | * 如果不在pig对象中的clone方法写下面这一句
87 | * pig.mBirthday = (Date) pig.mBirthday.clone();
88 | * 就会出现问题(pig2也跟着改变时间了),所以必须要深克隆,就是加上上面的代码
89 | */
90 | System.out.println(pig1);
91 | System.out.println(pig2);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/prototype/deep_clone/Pig.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.prototype.deep_clone;
2 |
3 | import java.util.Date;
4 |
5 | /**
6 | * 深拷贝
7 | */
8 | public class Pig implements Cloneable{
9 | private String mName;
10 | private Date mBirthday;
11 |
12 | public Pig(String name, Date birthday) {
13 | this.mName = name;
14 | this.mBirthday = birthday;
15 | }
16 |
17 | public String getName() {
18 | return mName;
19 | }
20 |
21 | public void setName(String name) {
22 | this.mName = name;
23 | }
24 |
25 | public Date getBirthday() {
26 | return mBirthday;
27 | }
28 |
29 | public void setBirthday(Date birthday) {
30 | this.mBirthday = birthday;
31 | }
32 |
33 | @Override
34 | public String toString() {
35 | return "Pig{" +
36 | "name='" + mName + '\'' +
37 | ", birthday=" + mBirthday +
38 | '}'+super.toString();
39 | }
40 |
41 | /**
42 | * 重写clone 方法
43 | */
44 | @Override
45 | public Object clone() throws CloneNotSupportedException {
46 |
47 | //深克隆
48 | Pig pig = (Pig)super.clone();
49 | pig.mBirthday = (Date) pig.mBirthday.clone();
50 |
51 | return pig;
52 | }
53 |
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/prototype/shallow_clone/Mail.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.prototype.shallow_clone;
2 |
3 | /**
4 | * 实现Cloneable接口
5 | * 当前类是浅拷贝
6 | * 步骤1:创建Mail类,实现Cloneable共接口
7 | */
8 | public class Mail implements Cloneable{
9 |
10 | private String mName;
11 | private String mEmailAddress;
12 | private String mContent;
13 |
14 | public Mail() {
15 | System.out.println("无参构造方法");
16 | }
17 |
18 | public String getName() {
19 | return mName;
20 | }
21 |
22 | public void setName(String mName) {
23 | this.mName = mName;
24 | }
25 |
26 | public String getEmailAddress() {
27 | return mEmailAddress;
28 | }
29 |
30 | public void setEmailAddress(String mEmailAddress) {
31 | this.mEmailAddress = mEmailAddress;
32 | }
33 |
34 | public String getContent() {
35 | return mContent;
36 | }
37 |
38 | public void setContent(String mContent) {
39 | this.mContent = mContent;
40 | }
41 |
42 | @Override
43 | public String toString() {
44 | return "Mail{" +
45 | "mName='" + mName + '\'' +
46 | ", mEmailAddress='" + mEmailAddress + '\'' +
47 | ", mContent='" + mContent + '\'' +
48 | '}';
49 | }
50 |
51 | /**
52 | * 步骤2:重写clone 方法
53 | */
54 | @Override
55 | public Object clone() throws CloneNotSupportedException {
56 | System.out.println("重写Mail对象的clone方法");
57 | return super.clone();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/prototype/shallow_clone/MailUtil.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.prototype.shallow_clone;
2 |
3 | import java.text.MessageFormat;
4 |
5 | public class MailUtil {
6 |
7 | public static void sendMail(Mail mail){
8 | String outputContent = "向{0}同学,邮件地址:{1},邮件内容:{2}发送邮件成功";
9 | System.out.println(MessageFormat.format(outputContent,mail.getName(),mail.getEmailAddress(),mail.getContent()));
10 | }
11 |
12 | public static void saveOriginMailRecord(Mail mail){
13 | System.out.println("存储originMail记录,originMail:"+mail.getContent());
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/single/ContainerSingleton.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.single;
2 |
3 |
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | /**
8 | *容器的单例模式
9 | */
10 | public class ContainerSingleton {
11 |
12 | private ContainerSingleton() {
13 |
14 | }
15 |
16 | private static Map singletonMap = new HashMap<>();
17 |
18 | public static void putInstance(String key, Object instance) {
19 | if (!singletonMap.containsKey(key)) {
20 | singletonMap.put(key, instance);
21 | }
22 | }
23 |
24 | public static Object getInstance(String key) {
25 | return singletonMap.get(key);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/single/EnumInstance.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.single;
2 |
3 | /**
4 | * 枚举方式的单例,
5 | * 天然抵挡反射破解和序列化破解
6 | */
7 | public enum EnumInstance {
8 |
9 | INSTANCE;
10 |
11 | private Object data;
12 |
13 | public Object getData() {
14 | return data;
15 | }
16 |
17 | public void setData(Object data) {
18 | this.data = data;
19 | }
20 |
21 | public static EnumInstance getInstance(){
22 | return INSTANCE;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/single/HungrySingleton.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.single;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 饿汉式
7 | * 1.构造函数私有化
8 | * 2.创建全局静态final变量
9 | * 3.对外提供一个静态方法
10 | */
11 | public class HungrySingleton implements Serializable{
12 |
13 | //步骤1:构造函数私有化
14 | private HungrySingleton() {
15 | //防止反射破解,这一招对饿汉式和静态内部类都好使,对懒汉式不好使
16 | if(HUNGRYSINGLETON!=null){
17 | throw new RuntimeException("单例构造器禁止反射调用");
18 | }
19 | }
20 |
21 | //步骤2:创建全局静态final变量
22 | private static final HungrySingleton HUNGRYSINGLETON = new HungrySingleton();
23 |
24 | //步骤3:对外提供一个静态方法
25 | public static HungrySingleton getInstance() {
26 | return HUNGRYSINGLETON;
27 | }
28 |
29 | /**
30 | * 一旦单例模式涉及到序列化和反序列化,一定要小心单例被破坏掉
31 | * 这个方法是反射调用的,如果不写这个方法,序列化就会破坏单例(翻看ObjectInputStream源码得知的)
32 | */
33 | private Object readResolve(){
34 | return HUNGRYSINGLETON;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/single/LazyDoubleCheckSingleton.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.single;
2 |
3 | /**
4 | * 双重校验的懒汉式单例模式
5 | * 但是反射依然可以破解懒汉式单例,因为如果反射先进来,就可以拿到这个类的所有东西,然后创建对象
6 | *
7 | * 1.构造函数私有化
8 | * 2.创建全局静态final变量
9 | * 3.对外提供一个静态方法
10 | */
11 |
12 | public class LazyDoubleCheckSingleton {
13 |
14 | //步骤1:构造函数私有化
15 | private LazyDoubleCheckSingleton() {
16 |
17 | /**
18 | * 防止反射破解,这一招对饿汉式和静态内部类都好使,对懒汉式不好使
19 | * 因为,如果反射的创建方式先进来,就能直接创建对象.
20 | * 然后正常的创建方式后进来,又能创建对象,就把这个单例破坏了.
21 | */
22 | if(mInstance!=null){
23 | throw new RuntimeException("单例构造器禁止反射调用");
24 | }
25 | }
26 |
27 | //步骤2:创建全局静态私有变量
28 | private static LazyDoubleCheckSingleton mInstance = null;
29 |
30 | //步骤3:对外提供一个静态方法,里面进行了双重校验
31 | public static LazyDoubleCheckSingleton getInstance() {
32 | if (mInstance == null) {
33 | synchronized (LazyDoubleCheckSingleton.class) {
34 | if (mInstance == null) {
35 | mInstance = new LazyDoubleCheckSingleton();
36 | }
37 | }
38 | }
39 | return mInstance;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/single/StaticInnerClassSingleton.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.single;
2 |
3 | /**
4 | * 静态内部类的单例模式
5 | */
6 | public class StaticInnerClassSingleton {
7 |
8 |
9 | //步骤1:构造函数私有化
10 | private StaticInnerClassSingleton(){
11 | //防止反射破解,这一招对饿汉式和静态内部类单例都好使,对懒汉式不好使
12 | if(Holder.INSTANCE!=null){
13 | throw new RuntimeException("单例构造器禁止反射调用");
14 | }
15 | }
16 |
17 | //步骤3:对外提供一个静态方法
18 | public static StaticInnerClassSingleton getInstance() {
19 | return Holder.INSTANCE;
20 | }
21 |
22 | /**
23 | * 步骤2:创建静态内部类对象
24 | * 静态内部类
25 | */
26 | private static class Holder {
27 | private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/creational/single/TestSingleton.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.creational.single;
2 |
3 | import android.os.Environment;
4 |
5 | import java.io.File;
6 | import java.io.FileInputStream;
7 | import java.io.FileOutputStream;
8 | import java.io.ObjectInputStream;
9 | import java.io.ObjectOutputStream;
10 | import java.lang.reflect.Constructor;
11 |
12 | /**
13 | * 单例设计模式
14 | * 定义:保证一个类仅有一个实例,并提供一个全局访问点
15 | * 类型:创建型
16 | * 适用场景:
17 | * 1.想确保任何情况下都绝对只有一个实例
18 | * 优点:
19 | * 1.在内存里只有一个实例,减少了内存开销
20 | * 2.可以避免对资源的多重占用
21 | * 3.设置了全局访问点,严格控制访问
22 | * 缺点:
23 | * 1.没有接口,扩展困难
24 | * 扩展:
25 | * 1.线程安全
26 | * 2.延迟加载
27 | * 3.序列化和反序列化安全
28 | * 4.反射可以破解懒汉式(哪怕双重校验加锁也不好使),但是饿汉式和静态内部类可以防御
29 | *
30 | */
31 | public class TestSingleton {
32 |
33 |
34 | public static void test()throws Exception {
35 | staticInnerClassSingleton();//静态内部类方式,通过反射的方式去破解单例,可以防御
36 | hungrySingleton1();//饿汉式,通过序列化的方式去破解单例,可以防御
37 | hungrySingleton2();//饿汉式,通过反射的方式去破解单例,可以防御
38 | LazyDoubleCheckSingleton();//懒汉式,通过反射的方式去破解单例,防御不了!!!!!!
39 | enumInstance();//枚举式,免疫反射和序列化破解单例
40 | containerSingleton();
41 | }
42 |
43 | /**
44 | * 静态内部类单例
45 | */
46 | private static void staticInnerClassSingleton() {
47 | StaticInnerClassSingleton single1 = StaticInnerClassSingleton.getInstance();
48 | StaticInnerClassSingleton single2 = StaticInnerClassSingleton.getInstance();
49 | //比较其地址值
50 | System.out.println("single1: "+single1);
51 | System.out.println("single2"+single2);
52 | System.out.println(single1==single2);
53 | }
54 |
55 | /**
56 | * 饿汉式
57 | * 通过序列化的方式去破解单例,可以防御
58 | */
59 | private static void hungrySingleton1() throws Exception{
60 | HungrySingleton singleton = HungrySingleton.getInstance();
61 |
62 | String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath();
63 | //把该对象序列化到本地文件中
64 | ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(absolutePath+"/singleton_file"));
65 | oos.writeObject(singleton);
66 |
67 | //然后在取出来
68 | File file = new File(absolutePath+"/singleton_file");
69 | ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
70 | HungrySingleton newInstance = (HungrySingleton) ois.readObject();
71 |
72 | //比较其地址值
73 | System.out.println("singleton: "+singleton);
74 | System.out.println("newInstance"+newInstance);
75 | System.out.println(singleton==newInstance);
76 | }
77 |
78 | /**
79 | * 饿汉式
80 | * 通过反射的方式去破解单例,可以防御
81 | */
82 | private static void hungrySingleton2() throws Exception{
83 | //正常方式创建对象
84 | HungrySingleton oldInstance = HungrySingleton.getInstance();
85 |
86 | //反射的方式创建
87 | Class objectClass= HungrySingleton.class;
88 | Constructor constructor =objectClass.getDeclaredConstructor();
89 | constructor.setAccessible(true);//暴力访问
90 | HungrySingleton newInstance = (HungrySingleton) constructor.newInstance();
91 |
92 |
93 | //比较其地址值
94 | System.out.println("oldInstance: "+oldInstance);
95 | System.out.println("newInstance"+newInstance);
96 | System.out.println(oldInstance==newInstance);
97 | }
98 |
99 | /**
100 | * 双重校验懒汉式单例
101 | * 通过反射的方式去破解单例,防御不了,哪怕在构造方法中进行判断,抛出异常,依然防御不了.
102 | * 因为如果多线程的话,反射的创建方式有可能先进来,就能创建对象.
103 | * 然后正常方式创建对象,又创建了对象.
104 | */
105 | private static void LazyDoubleCheckSingleton() throws Exception {
106 | //反射的方式创建
107 | Class objectClass= LazyDoubleCheckSingleton.class;
108 | Constructor constructor =objectClass.getDeclaredConstructor();
109 | constructor.setAccessible(true);//暴力访问
110 | LazyDoubleCheckSingleton newInstance = (LazyDoubleCheckSingleton) constructor.newInstance();
111 |
112 | //正常方式创建
113 | LazyDoubleCheckSingleton oldInstance = LazyDoubleCheckSingleton.getInstance();
114 |
115 | //比较其地址值
116 | System.out.println("oldInstance: "+oldInstance);
117 | System.out.println("newInstance"+newInstance);
118 | System.out.println(oldInstance==newInstance);
119 | }
120 |
121 | /**
122 | * 枚举的单例模式
123 | * 反射破解不了单例,然后序列化也破解不了单例
124 | */
125 | private static void enumInstance() {
126 | //正常方式创建
127 | EnumInstance oldInstance = EnumInstance.getInstance();
128 | Object newData1 = oldInstance.getData();
129 | Object newData2 = oldInstance.getData();
130 | //比较其地址值
131 | System.out.println("newData1: "+newData1);
132 | System.out.println("newData2"+newData2);
133 | System.out.println(newData1==newData2);
134 |
135 | }
136 |
137 | /**
138 | * 容器的单例模式
139 | */
140 | private static void containerSingleton() {
141 | ContainerSingleton.putInstance("city","北京");
142 | ContainerSingleton.putInstance("风清扬","独孤九剑");
143 |
144 | String str = (String) ContainerSingleton.getInstance("风清扬");
145 | System.out.println(str);
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/TestAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter;
2 |
3 |
4 | import com.yadong.pattern.structural.adapter.class_adapter.Adapter;
5 | import com.yadong.pattern.structural.adapter.class_adapter.ConcreteTarget;
6 | import com.yadong.pattern.structural.adapter.class_adapter.Target;
7 | import com.yadong.pattern.structural.adapter.voltage_adapter.DC5;
8 | import com.yadong.pattern.structural.adapter.voltage_adapter.PowerAdapter;
9 |
10 | /**
11 | * 适配器模式
12 | * 定义:将一个类的接口转换成客户期望的另一个接口
13 | * 特征:使原本接口不兼容的类可以一起工作
14 | * 类型:结构型
15 | * 适用场景:
16 | * 1.已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)
17 | * 2.不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品,不同厂家造成功能类似而接口不相同情况下的解决方案
18 | * 优点:
19 | * 1.能提高类的透明性和复用,现有的类复用但不需要改变
20 | * 2.目标类和适配器类解耦,提高程序扩展性
21 | * 3.符合开闭原则
22 | * 缺点:
23 | * 1.适配器编写过程要全面考虑,可能会增加系统的复杂性
24 | * 2.增加系统代码可读的难度
25 | * 扩展:
26 | * 1.类适配器---通过类继承来实现的
27 | * 2.对象适配器---符合组合复用原则,使用委托机制
28 | */
29 | public class TestAdapter {
30 |
31 |
32 | /**
33 | * 类适配器的模型
34 | * 继承的方式
35 | * 四个角色:
36 | * 1.被适配者
37 | * 2.适配者
38 | * 3.目标接口
39 | * 4.目标接口的实现类
40 | * 目的就是让适配者通过他的一顿操作,达到融合被适配者和目标接口到一个类中.
41 | */
42 | public static void classAdapterTest(){
43 | Target target = new ConcreteTarget();
44 | target.request();
45 |
46 | Target adapterTarget = new Adapter();
47 | adapterTarget.request();
48 | }
49 |
50 |
51 | /**
52 | * 对象适配器
53 | * 组合的方式
54 | * 四个角色:
55 | * 1.被适配者
56 | * 2.适配者
57 | * 3.目标接口
58 | * 4.目标接口的实现类
59 | * 目的就是让适配者通过他的一顿操作,达到融合被适配者和目标接口到一个类中.
60 | */
61 | public static void objectAdapterTest(){
62 |
63 | com.yadong.pattern.structural.adapter.object_adapter.Target target = new com.yadong.pattern.structural.adapter.object_adapter.ConcreteTarget();
64 | target.request();
65 |
66 |
67 | com.yadong.pattern.structural.adapter.object_adapter.Target adapter = new com.yadong.pattern.structural.adapter.object_adapter.Adapter();
68 | adapter.request();
69 |
70 | }
71 |
72 | /**
73 | * 对象适配器
74 | * 场景:把220V的电压通过手机充电器转换成5V的电压给手机进行充电
75 | * 组合的方式
76 | * 四个角色:
77 | * 1.被适配者(AC220)
78 | * 2.适配者(PowerAdapter)
79 | * 3.目标接口(DC5)
80 | * 4.目标接口的实现类(老项目的目标接口的实现类,这里面没有,如果有,可以把代码移到适配者中)
81 | * 目的就是让适配者(PowerAdapter)通过他的一顿操作,达到融合被适配者(AC220)和目标接口(DC5)到一个类中.
82 | */
83 | public static void powerAdapter(){
84 | DC5 dc5 = new PowerAdapter();
85 | dc5.outputDC5V();
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/class_adapter/Adaptee.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter.class_adapter;
2 |
3 | /**
4 | * 被适配者
5 | */
6 | public class Adaptee {
7 |
8 | public void adapteeRequest(){
9 | System.out.println("被适配者的方法");
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/class_adapter/Adapter.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter.class_adapter;
2 |
3 | /**
4 | * 适配器来适配 被适配者,来达到target的目标
5 | * 这种是继承的模式
6 | */
7 | public class Adapter extends Adaptee implements Target{
8 |
9 | @Override
10 | public void request() {
11 | //...
12 | super.adapteeRequest();
13 | //...
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/class_adapter/ConcreteTarget.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter.class_adapter;
2 |
3 | /**
4 | * 具体的目标 实现接口
5 | */
6 | public class ConcreteTarget implements Target {
7 |
8 | @Override
9 | public void request() {
10 | System.out.println("concreteTarget目标方法");
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/class_adapter/Target.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter.class_adapter;
2 |
3 | /**
4 | * 目标接口
5 | */
6 | public interface Target {
7 | void request();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/object_adapter/Adaptee.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter.object_adapter;
2 |
3 | /**
4 | * 被适配者
5 | */
6 | public class Adaptee {
7 |
8 | public void adapteeRequest() {
9 | System.out.println("被适配者的方法");
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/object_adapter/Adapter.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter.object_adapter;
2 |
3 | /**
4 | * 适配器
5 | * 这种是组合的方式
6 | */
7 | public class Adapter implements Target{
8 |
9 | private Adaptee adaptee = new Adaptee();
10 |
11 | @Override
12 | public void request() {
13 | //...
14 | adaptee.adapteeRequest();
15 | //...
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/object_adapter/ConcreteTarget.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter.object_adapter;
2 |
3 | /**
4 | *
5 | */
6 | public class ConcreteTarget implements Target {
7 |
8 | @Override
9 | public void request() {
10 | System.out.println("concreteTarget目标方法");
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/object_adapter/Target.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter.object_adapter;
2 |
3 | /**
4 | *
5 | */
6 | public interface Target {
7 | void request();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/voltage_adapter/AC220.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter.voltage_adapter;
2 |
3 | /**
4 | * 220V的电压
5 | */
6 | public class AC220 {
7 | public int outputAC220V(){
8 | int output = 220;
9 | System.out.println("输出交流电"+output+"V");
10 | return output;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/voltage_adapter/DC5.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter.voltage_adapter;
2 |
3 | public interface DC5 {
4 | int outputDC5V();
5 | }
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/adapter/voltage_adapter/PowerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.adapter.voltage_adapter;
2 |
3 | /**
4 | * 适配器
5 | * 把220V的电转换成5V的电,采用的是组合的方式,把AC220对象给new出来,然后实现DC5接口
6 | */
7 | public class PowerAdapter implements DC5 {
8 |
9 | private AC220 ac220=new AC220();
10 |
11 | @Override
12 | public int outputDC5V() {
13 | int adapterInput = ac220.outputAC220V();
14 |
15 | //模拟变压器
16 | int adapterOutput = adapterInput/44;
17 |
18 | System.out.println("使用PowerAdapter输入AC:"+adapterInput+"V"+"输出DC:"+adapterOutput+"V");
19 | return adapterOutput;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/bridge/ABCBank.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.bridge;
2 |
3 | /**
4 | * 中国农业银行
5 | */
6 | public class ABCBank extends Bank {
7 | public ABCBank(Account account) {
8 | super(account);
9 | }
10 |
11 | @Override
12 | Account openAccount() {
13 | System.out.println("打开中国农业银行账号");
14 | account.openAccount();
15 | return account;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/bridge/Account.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.bridge;
2 |
3 | /**
4 | * 账号
5 | */
6 | public interface Account {
7 | //打开账号
8 | Account openAccount();
9 |
10 | //查看账号的类型(是活期还是定期)
11 | void showAccountType();
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/bridge/Bank.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.bridge;
2 |
3 | /**
4 | * 银行
5 | */
6 | public abstract class Bank {
7 | //通过组合的方式建立两个类的连线
8 | protected Account account;
9 |
10 | public Bank(Account account) {
11 | this.account = account;
12 | }
13 |
14 | abstract Account openAccount();
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/bridge/DepositAccount.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.bridge;
2 |
3 | /**
4 | * 定期账号
5 | */
6 | public class DepositAccount implements Account {
7 | @Override
8 | public Account openAccount() {
9 | System.out.println("打开定期账号");
10 | return new DepositAccount();
11 | }
12 |
13 | @Override
14 | public void showAccountType() {
15 | System.out.println("这是一个定期账号");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/bridge/ICBCBank.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.bridge;
2 |
3 | /**
4 | * 中国工商银行
5 | */
6 | public class ICBCBank extends Bank {
7 | public ICBCBank(Account account) {
8 | super(account);
9 | }
10 |
11 | @Override
12 | Account openAccount() {
13 | System.out.println("打开中国工商银行账号");
14 | account.openAccount();
15 | return account;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/bridge/SavingAccount.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.bridge;
2 |
3 | /**
4 | * 活期账号
5 | */
6 | public class SavingAccount implements Account {
7 | @Override
8 | public Account openAccount() {
9 | System.out.println("打开活期账号");
10 | //...
11 | return new SavingAccount();
12 | }
13 |
14 | @Override
15 | public void showAccountType() {
16 | System.out.println("这是一个活期账号");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/bridge/TestBridge.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.bridge;
2 |
3 | /**
4 | * 桥接模式
5 | * 定义:将抽象部分与它的具体实现部分分离,使它们都可以独立地变换
6 | * 特征:通过组合的方式建立两个类之间的联系,而不是继承
7 | * 类型:结构型
8 | *
9 | * 适用场景:
10 | * 1.抽象和具体之间增加更多的灵活性
11 | * 2.一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展
12 | * 3.不希望使用继承,或因为多层继承导致系统类的个数剧增
13 | * 优点:
14 | * 1.分离抽象部分和具体实现部分
15 | * 2.提高了系统的可扩展性
16 | * 3.符合开闭原则
17 | * 4.符合合成复用原则
18 | * 缺点:
19 | * 1.增加了系统的理解和设计难度
20 | * 2.需要正确的识别出系统中两个独立变化的维度
21 | */
22 | public class TestBridge {
23 |
24 |
25 | /**
26 | * 抽象和实现分离,这是最重要的
27 | * 场景:中国有很多银行,有农业银行和工商银行,有自己的账号,然后分为定期和活期,我们想一下,一块是银行,一块是账号
28 | * 目的:以后银行会越来越多,希望用桥接模式去进行设计
29 | */
30 | public static void test() {
31 | //工商银行,然后账号类型是 定期
32 | Bank icbcBank = new ICBCBank(new DepositAccount());
33 | Account icbcAccount = icbcBank.openAccount();
34 | icbcAccount.showAccountType();
35 |
36 | //工商银行,然后账号类型是 活期
37 | Bank icbcBank2 = new ICBCBank(new SavingAccount());
38 | Account icbcAccount2 = icbcBank2.openAccount();
39 | icbcAccount2.showAccountType();
40 |
41 | //农业银行,然后账号类型是 活期
42 | Bank abcBank = new ABCBank(new SavingAccount());
43 | Account abcAccount = abcBank.openAccount();
44 | abcAccount.showAccountType();
45 |
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/composite/CatalogComponent.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.composite;
2 |
3 | /**
4 | * 抽象类
5 | */
6 | public abstract class CatalogComponent {
7 | public void add(CatalogComponent catalogComponent) {
8 | throw new UnsupportedOperationException("不支持添加操作");
9 | }
10 |
11 | public void remove(CatalogComponent catalogComponent) {
12 | throw new UnsupportedOperationException("不支持删除操作");
13 | }
14 |
15 |
16 | public String getName(CatalogComponent catalogComponent) {
17 | throw new UnsupportedOperationException("不支持获取名称操作");
18 | }
19 |
20 |
21 | public double getPrice(CatalogComponent catalogComponent) {
22 | throw new UnsupportedOperationException("不支持获取价格操作");
23 | }
24 |
25 |
26 | public void print() {
27 | throw new UnsupportedOperationException("不支持打印操作");
28 | }
29 |
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/composite/Course.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.composite;
2 |
3 | /**
4 | * 课程
5 | */
6 | public class Course extends CatalogComponent {
7 | private String name;
8 | private double price;
9 |
10 | public Course(String name, double price) {
11 | this.name = name;
12 | this.price = price;
13 | }
14 |
15 | @Override
16 | public String getName(CatalogComponent catalogComponent) {
17 | return this.name;
18 | }
19 |
20 | @Override
21 | public double getPrice(CatalogComponent catalogComponent) {
22 | return this.price;
23 | }
24 |
25 | @Override
26 | public void print() {
27 | System.out.println("Course Name:" + name + " Price:" + price);
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/composite/CourseCatalog.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.composite;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 课程目录
8 | */
9 | public class CourseCatalog extends CatalogComponent {
10 | private List items = new ArrayList<>();
11 | private String name;
12 | private Integer level;
13 |
14 |
15 | public CourseCatalog(String name, Integer level) {
16 | this.name = name;
17 | this.level = level;
18 | }
19 |
20 | @Override
21 | public void add(CatalogComponent catalogComponent) {
22 | items.add(catalogComponent);
23 | }
24 |
25 | @Override
26 | public String getName(CatalogComponent catalogComponent) {
27 | return this.name;
28 | }
29 |
30 | @Override
31 | public void remove(CatalogComponent catalogComponent) {
32 | items.remove(catalogComponent);
33 | }
34 |
35 | @Override
36 | public void print() {
37 | System.out.println(this.name);
38 | for (CatalogComponent catalogComponent : items) {
39 | if (this.level != null) {
40 | for (int i = 0; i < this.level; i++) {
41 | System.out.print(" ");
42 | }
43 | }
44 | catalogComponent.print();
45 | }
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/composite/TestComposite.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.composite;
2 |
3 | /**
4 | * 组合模式
5 | * 定义:将对象组合成树形结构以表示【部分-整体】的层次结构
6 | * 特征:组合模式使客户端对单个对象和组合对象保持一致的方式处理
7 | * 类型:结构型
8 | * 适用场景:
9 | * 1.希望客户端可以忽略组合对象与单个对象的差异时
10 | * 2.处理一个树形结构时
11 | * 优点:
12 | * 1.清楚的定义分层次的复杂对象,表示对象的全部或部分层次
13 | * 2.让客户端忽略了层次的差异,方便对整个层次结构进行控制
14 | * 3.简化客户端的代码
15 | * 4.符合开闭原则
16 | * 缺点:
17 | * 1.限制类型时会较为复杂
18 | * 2.使设计变的更加抽象
19 | */
20 | public class TestComposite {
21 |
22 |
23 | /**
24 | * 场景:有很多课程,然后也有很多目录,需要把这些课程进行树桩结构分类
25 | */
26 | public static void test() {
27 | //二级目录
28 | CatalogComponent operatingSystem = new CourseCatalog("操作系统课程目录",2);
29 | CatalogComponent linuxCourse = new Course("Linux课程",100);
30 | CatalogComponent windowsCourse = new Course("Windows课程",120);
31 | operatingSystem.add(linuxCourse);
32 | operatingSystem.add(windowsCourse);
33 |
34 |
35 | //二级目录
36 | CatalogComponent javaCourseCatalog = new CourseCatalog("Java课程目录",2);
37 | CatalogComponent javaBase = new Course("Java基础",66);
38 | CatalogComponent designPattern = new Course("Java设计模式",77);
39 | javaCourseCatalog.add(javaBase);
40 | javaCourseCatalog.add(designPattern);
41 |
42 |
43 | //一级目录(主目录)
44 | CatalogComponent mainCourseCatalog = new CourseCatalog("课程主目录",1);
45 | mainCourseCatalog.add(linuxCourse);
46 | mainCourseCatalog.add(windowsCourse);
47 | mainCourseCatalog.add(javaCourseCatalog);
48 | mainCourseCatalog.print();
49 |
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/decorator/DecoratorTest.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.decorator;
2 |
3 | import com.yadong.pattern.structural.decorator.v1.BatterCakeWithEgg;
4 | import com.yadong.pattern.structural.decorator.v1.BatterCakeWithEggSausage;
5 | import com.yadong.pattern.structural.decorator.v2.ABatterCake;
6 | import com.yadong.pattern.structural.decorator.v2.BatterCake;
7 | import com.yadong.pattern.structural.decorator.v2.EggDecorator;
8 | import com.yadong.pattern.structural.decorator.v2.SausageDecorator;
9 |
10 | /**
11 | * 装饰器模式
12 | * 定义:在不改变原有对象的基础之上,将功能附加到对象上
13 | * 特征:提供了比继承更有弹性的提单方案(扩展原有对象功能)
14 | * 类型:结构型
15 | *
16 | * 适用场景:
17 | * 1.扩展一个类的功能或给一个类添加附加职责
18 | * 2.动态的给一个对象添加功能,这些功能可以再动态的撤销
19 | * 优点:
20 | * 1.继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能
21 | * 2.通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果
22 | * 3.符合开闭原则
23 | * 缺点:
24 | * 1.会出现更多的代码,更多的类,增加程序复杂性
25 | * 2.动态装饰时,多层装饰会更复杂
26 | */
27 | public class DecoratorTest {
28 |
29 | /**
30 | * 这个只是铺垫
31 | * 场景:饿了,想买个煎饼吃,然后可以只买煎饼,还能加蛋,还能加烤肠
32 | */
33 | public static void testV1(){
34 |
35 | //煎饼
36 | com.yadong.pattern.structural.decorator.v1.BatterCake battercake =new com.yadong.pattern.structural.decorator.v1.BatterCake();
37 | System.out.println(battercake.getDesc()+" 销售价格:"+battercake.cost());
38 |
39 | //煎饼加个蛋
40 | BatterCakeWithEgg battercakeWithEgg = new BatterCakeWithEgg();
41 | System.out.println(battercakeWithEgg.getDesc()+" 销售价格:"+battercakeWithEgg.cost());
42 |
43 | //煎饼加个蛋在加个烤肠
44 | BatterCakeWithEggSausage battercakeWithEggSausage = new BatterCakeWithEggSausage();
45 | System.out.println(battercakeWithEggSausage.getDesc()+" 销售价格:"+battercakeWithEggSausage.cost());
46 |
47 | }
48 |
49 |
50 | /**
51 | * 真正的装饰者模式
52 | * 这个时候一个小伙伴想吃个煎饼,加俩蛋,加3根烤肠,上面的v1版本就不好使了,这时候就要装饰模式登场了
53 | *
54 | * 抽象的实体类 抽象的煎饼
55 | * 确定的实体类 确定的煎饼,继承于抽象的煎饼
56 | *
57 | * 抽象的装饰者 继承于抽象的实体类(就是抽象的煎饼)
58 | * 确定的装饰者 蛋和烤肠,继承于抽象的装饰者
59 | *
60 | * 被装饰的实体是煎饼,然后装饰者是蛋和烤肠,4个角色缺一不可
61 | */
62 | public static void testV2(){
63 | ABatterCake batterCake;
64 | //煎饼
65 | batterCake = new com.yadong.pattern.structural.decorator.v2.BatterCake();
66 | //加蛋
67 | batterCake = new EggDecorator(batterCake);
68 | //在加蛋
69 | batterCake = new EggDecorator(batterCake);
70 | //加个烤肠
71 | batterCake = new SausageDecorator(batterCake);
72 | /**
73 | * 输出结果:
74 | * 8+1+1+2=12块钱
75 | * 煎饼加一个鸡蛋加一个鸡蛋加一个烤肠 销售价格:12
76 | */
77 | System.out.println(batterCake.getDesc()+" 销售价格:"+batterCake.cost());
78 |
79 |
80 | /**
81 | * 另外一种写法,连起来写
82 | * 输出结果:
83 | * 煎饼加一个鸡蛋加一个烤肠加一个烤肠 销售价格:13
84 | * 煎饼+蛋+烤肠+烤肠
85 | * 8+1+2+2=13块钱
86 | */
87 | SausageDecorator sausageBatterCake= new SausageDecorator(new SausageDecorator(new EggDecorator(new BatterCake())));
88 | System.out.println(sausageBatterCake.getDesc()+" 销售价格:"+sausageBatterCake.cost());
89 |
90 |
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/decorator/v1/BatterCake.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.decorator.v1;
2 |
3 | /**
4 | * 煎饼
5 | */
6 | public class BatterCake {
7 |
8 |
9 | public String getDesc(){
10 | return "煎饼";
11 | }
12 |
13 | /**
14 | * 成本8块钱
15 | */
16 | public int cost(){
17 | return 8;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/decorator/v1/BatterCakeWithEgg.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.decorator.v1;
2 |
3 | /**
4 | * 煎饼中加个蛋
5 | */
6 | public class BatterCakeWithEgg extends BatterCake {
7 |
8 | @Override
9 | public String getDesc() {
10 | return super.getDesc() + " 加一个鸡蛋";
11 | }
12 |
13 | /**
14 | * 成本加1块钱
15 | */
16 | @Override
17 | public int cost() {
18 | return super.cost() + 1;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/decorator/v1/BatterCakeWithEggSausage.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.decorator.v1;
2 |
3 | /**
4 | * 煎饼中加个蛋的基础上在加个烤肠
5 | */
6 | public class BatterCakeWithEggSausage extends BatterCakeWithEgg {
7 |
8 | @Override
9 | public String getDesc() {
10 | return super.getDesc()+ " 加一根烤肠";
11 | }
12 |
13 | /**
14 | * 成本有加了2块钱
15 | */
16 | @Override
17 | public int cost() {
18 | return super.cost()+2;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/decorator/v2/ABatterCake.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.decorator.v2;
2 |
3 | /**
4 | * 抽象的实体类
5 | * 抽象的煎饼
6 | */
7 | public abstract class ABatterCake {
8 |
9 | /**
10 | * 获取描述
11 | */
12 | public abstract String getDesc();
13 |
14 | /**
15 | * 成本价格
16 | */
17 | public abstract int cost();
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/decorator/v2/AbstractDecorator.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.decorator.v2;
2 |
3 | /**
4 | * 抽象的装饰类
5 | * 继承抽象的煎饼(ABatterCake),这个时候当前类(AbstractDecorator)和具体的煎饼类(BatterCake)都是继承于ABatterCake
6 | *
7 | * 因为要给煎饼进行装饰,所以如何让当前类和具体的煎饼类产生联系呢?
8 | * 可以通过两者共同的父类,可以把父类(ABatterCake)通过构造参数传递进来,这样具体的煎饼就能传进来了,就能在具体的煎饼上进行装饰
9 | *
10 | */
11 | public class AbstractDecorator extends ABatterCake{
12 |
13 |
14 | private ABatterCake mBatterCake;//抽象的煎饼,当然也可以传具体的煎饼
15 |
16 | public AbstractDecorator(ABatterCake mBatterCake) {
17 | this.mBatterCake = mBatterCake;
18 | }
19 |
20 |
21 | @Override
22 | public String getDesc() {
23 | return this.mBatterCake.getDesc();
24 | }
25 |
26 | @Override
27 | public int cost() {
28 | return this.mBatterCake.cost();
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/decorator/v2/BatterCake.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.decorator.v2;
2 |
3 | /**
4 | * 具体的实体类
5 | * 具体的煎饼
6 | */
7 | public class BatterCake extends ABatterCake {
8 |
9 | @Override
10 | public String getDesc() {
11 | return "煎饼";
12 | }
13 |
14 | @Override
15 | public int cost() {
16 | return 8;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/decorator/v2/EggDecorator.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.decorator.v2;
2 |
3 | /**
4 | * 鸡蛋装饰类
5 | */
6 | public class EggDecorator extends AbstractDecorator {
7 |
8 | public EggDecorator(ABatterCake mBatterCake) {
9 | super(mBatterCake);
10 | }
11 |
12 | @Override
13 | public String getDesc() {
14 | return super.getDesc()+"加一个鸡蛋";
15 | }
16 |
17 | @Override
18 | public int cost() {
19 | return super.cost()+1;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/decorator/v2/SausageDecorator.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.decorator.v2;
2 |
3 | /**
4 | * 烤肠装饰类
5 | */
6 | public class SausageDecorator extends AbstractDecorator {
7 |
8 | public SausageDecorator(ABatterCake mBatterCake) {
9 | super(mBatterCake);
10 | }
11 |
12 | @Override
13 | public String getDesc() {
14 | return super.getDesc()+"加一个烤肠";
15 | }
16 |
17 | @Override
18 | public int cost() {
19 | return super.cost()+2;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/facade/GiftExchangeService.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.facade;
2 |
3 | /**
4 | * 外观类
5 | *
6 | * 应用层(FacadeTest)不和这3个子系统通信,只是和外观类(GiftExchangeService)通信,然后外观类和3个子系统通信
7 | * 应用层(FacadeTest)<=>外观类(GiftExchangeService)<=>3个子系统(QualifyService,PointsPaymentService,LogisticsService)
8 | */
9 | public class GiftExchangeService {
10 |
11 | private QualifyService mQualifyService = new QualifyService();//资格兑换子系统
12 | private PointsPaymentService mPointsPaymentService = new PointsPaymentService();//积分支付子系统
13 | private LogisticsService mLogisticsService = new LogisticsService();//物流子系统
14 |
15 | public void giftExchange(PointGift pointsGift){
16 | if(mQualifyService.isAvailable(pointsGift)){
17 | //资格校验通过
18 | if(mPointsPaymentService.pay(pointsGift)){
19 | //如果支付积分成功
20 | String shippingOrderNo = mLogisticsService.shipGift(pointsGift);
21 | System.out.println("物流系统下单成功,订单号是:"+shippingOrderNo);
22 | }
23 | }
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/facade/LogisticsService.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.facade;
2 |
3 | /**
4 | * 物流服务子系统
5 | */
6 | public class LogisticsService {
7 |
8 | public String shipGift(PointGift pointsGift){
9 | //物流系统的对接逻辑
10 | System.out.println(pointsGift.getName()+"进入物流系统");
11 | String logisticsOrderNo = "666";//物流订单ID
12 | return logisticsOrderNo;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/facade/PointGift.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.facade;
2 |
3 | /**
4 | * 积分礼物类
5 | */
6 | public class PointGift {
7 |
8 | private String name;
9 |
10 | public PointGift(String name) {
11 | this.name = name;
12 | }
13 |
14 | public String getName() {
15 | return name;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/facade/PointsPaymentService.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.facade;
2 |
3 | /**
4 | * 积分支付子系统
5 | */
6 | public class PointsPaymentService {
7 | public boolean pay(PointGift pointsGift) {
8 | //扣减积分
9 | System.out.println("支付" + pointsGift.getName() + " 积分成功");
10 | return true;
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/facade/QualifyService.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.facade;
2 |
3 | /**
4 | * 资格兑换子系统
5 | */
6 | public class QualifyService {
7 |
8 | public boolean isAvailable(PointGift pointsGift){
9 | System.out.println("校验"+pointsGift.getName()+" 积分资格通过,库存通过");
10 | return true;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/facade/TestFacade.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.facade;
2 |
3 | /**
4 | *
5 | * 外观模式
6 | * 定义:又叫门面模式,提供了一个统一的接口,用来访问一个或多个子系统中的一群接口
7 | * 特征:外观模式定义了一个高层接口,让子系统更容易使用
8 | * 类型:结构性
9 | * 适用场景:
10 | * 1.子系统越来越复杂,增加外观模式提供简单调用接口
11 | * 2.构建多层结构,利用外观对象作为每层的入口,简化层间调用
12 | * 优点:
13 | * 1.简化了调用过程,无需了解深入子系统,防止带来风险
14 | * 2.减少系统依赖,松散耦合(客户端不和子系统直接交流,而是通过外观模式进行交流)
15 | * 3.更好的划分访问层次
16 | * 4.符合迪米特法则,即最少知道原则(客户端不需要了解子系统内部的实现,只需要和外观类交互就完了)
17 | * 缺点:
18 | * 1.增加子系统,扩展子系统行为容易引入风险
19 | * 2.不符合开闭原则
20 | *
21 | */
22 | public class TestFacade {
23 |
24 |
25 | /**
26 | * 现在的业务场景:
27 | * 某电商平台上面有积分可以换小礼物,然后需要
28 | * 1.资格兑换子系统(就是看你账号上积分是否足够兑换物品)
29 | * 2.积分支付子系统
30 | * 3.物流子系统
31 | *
32 | * 总结:
33 | * 就是说兑换这个小礼物需要走3个子系统,然后我们提供一个外观类对象(GiftExchangeService),提供统一的入口,
34 | * 让外观类(GiftExchangeService)去和3个子系统通信,然后我们的应用层(也就是FacadeTest这个类)只需要和外观类通信就完了
35 | * 应用层(TestFacade)<=>外观类(GiftExchangeService)<=>3个子系统(QualifyService,PointsPaymentService,LogisticsService)
36 | */
37 | public static void test(){
38 | PointGift pointsGift = new PointGift("鼠标");
39 | GiftExchangeService giftExchangeService = new GiftExchangeService();
40 | giftExchangeService.giftExchange(pointsGift);
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/flyweight/Employee.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.flyweight;
2 |
3 | /**
4 | * 员工接口
5 | */
6 | public interface Employee {
7 | void report();
8 | }
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/flyweight/EmployeeFactory.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.flyweight;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * 员工 工厂
8 | */
9 | public class EmployeeFactory {
10 |
11 | private static final Map EMPLOYEE_MAP = new HashMap<>();
12 |
13 |
14 | /**
15 | * 根据部门去获取部门经理
16 | */
17 | public static Employee getManager(String department){
18 | Manager manager = (Manager) EMPLOYEE_MAP.get(department);
19 |
20 | if(manager == null){
21 | manager = new Manager(department);
22 | System.out.print("创建部门经理:"+department);
23 |
24 | String reportContent = department+"部门汇报:此次报告的主要内容是......";
25 | manager.setReportContent(reportContent);
26 | System.out.println(" 创建报告:"+reportContent);
27 |
28 | //存到map集合中
29 | EMPLOYEE_MAP.put(department,manager);
30 |
31 | }
32 | return manager;
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/flyweight/Manager.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.flyweight;
2 |
3 | /**
4 | * 部门经理 也属于员工
5 | */
6 | public class Manager implements Employee {
7 |
8 | private String department;//所属部门
9 | private String reportContent;//报告内容
10 |
11 | public Manager(String department) {
12 | this.department = department;
13 | }
14 |
15 | @Override
16 | public void report() {
17 | System.out.println(reportContent);
18 | }
19 |
20 |
21 | /**
22 | * 设置报告内容
23 | */
24 | public void setReportContent(String reportContent) {
25 | this.reportContent = reportContent;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/flyweight/TestFlyweight.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.flyweight;
2 |
3 |
4 | /**
5 | * 享元
6 | * 定义:提供了减少对象数量从而改善应用所需的对象结构的方式
7 | * 特征:运用共享技术有效地支持大量细粒度的对象
8 | * 类型:结构型
9 | *
10 | * 适用场景:
11 | * 1.常常应用于系统底层的开发,以便解决系统的性能问题
12 | * 2.系统有大量相似对象,需要缓冲池的场景
13 | * 优点:
14 | * 1.减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率
15 | * 2.减少内存之外的其他资源占用
16 | * 缺点:
17 | * 1.关注内/外部状态,关注线程安全问题
18 | * 2.使系统,程序的逻辑复杂化
19 | * 扩展:
20 | * 1.内部状态, 可以认为是享元对象的属性,不随着环境的改变而改变
21 | * 2.外部状态,通过方法的参数传过来一个状态,会随着环境的改变而改变
22 | */
23 | public class TestFlyweight {
24 |
25 |
26 | private static final String departments[] = {"技术", "综合管理", "人事", "销售"};
27 |
28 |
29 | /**
30 | * 背景:年底了,部门经理需要做报告
31 | */
32 | public static void test() {
33 | for (int i = 0; i < 10; i++) {
34 | String department = departments[(int) (Math.random() * departments.length)];
35 | Manager manager = (Manager) EmployeeFactory.getManager(department);
36 | manager.report();
37 | }
38 |
39 | }
40 |
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/proxy/AddController.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.proxy;
2 |
3 | /**
4 | * 委托方,一般下,委托方定义接口(就是DataInterface)
5 | *
6 | * 添加数据 页面
7 | */
8 |
9 | public class AddController {
10 |
11 |
12 | //定义接口
13 | public DataInterface mDataInterface;
14 |
15 |
16 | public void addEvent(){
17 |
18 | //使用接口中的方法
19 | mDataInterface.addData(this,"黄晓明");
20 | }
21 |
22 | }
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/proxy/ContactController.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.proxy;
2 |
3 | /**
4 | *
5 | * 代理方,实现接口
6 | *
7 | *
8 | * 联系人页面
9 | *
10 | */
11 |
12 | //实现接口
13 | public class ContactController implements DataInterface{
14 |
15 | @Override
16 | public void addData(AddController page, String name) {
17 |
18 | System.out.println("ContactController 添加数据成功 "+page.toString()+ " 名字:"+ name);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/proxy/DataInterface.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.proxy;
2 |
3 | /**
4 | *
5 | */
6 |
7 | public interface DataInterface {
8 |
9 | /**
10 | * 添加数据的方法
11 | */
12 | void addData(AddController controller, String name);
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/yadong/pattern/structural/proxy/ProxyTest.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern.structural.proxy;
2 |
3 | /**
4 | * 代理模式
5 | * 定义:为其他对象提供一种代理,以控制对这个对象的访问
6 | * 特征:代理对象在客户端和目标对象之间起到中介的作用
7 | * 类型:结构型
8 | *
9 | * 适用场景:
10 | * 1.保护目标对象
11 | * 2.增强目标对象
12 | * 优点:
13 | * 1.代理模式能将代理对象与真实被调用的目标对象分离
14 | * 2.一定程度上降低了系统的耦合度,扩展性好
15 | * 3.保护目标对象
16 | * 4.增强目标对象
17 | * 缺点:
18 | * 1.代理模式会早场系统设计中类的数目增加
19 | * 2.在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢
20 | * 3.增加系统的复杂度
21 | */
22 | public class ProxyTest {
23 |
24 | /**
25 | * 代理模式
26 | * 通过接口的方式 传递数据
27 | * 现在有一个 添加页面,联系人页面,当在添加页面中添加数据的时候,要把数据传递到联系人页面显示
28 | *
29 | * 1.先定义接口,该接口中,有一个方法,这个方法有两个参数,1.要传出去数据的那个页面对象 2.数据
30 | * 2.联系人页面ContactController 实现这个接口,和实现方法(此时ContactController是接口的实现类)
31 | * 2.AddController中持有接口的字段,把上面这个接口的实现类赋值给AddController中的接口字段
32 | * 3.当添加页面中的添加事件被触发的时候,让这个接口的实现类调用接口中的方法,从而实现了数据的传递
33 | *
34 | * 委托方和代理方
35 | * 委托方定义接口和使用接口中的方法
36 | * 代理方把代理对象传给委托方并实现委托方的接口,从而实现代理模式
37 | */
38 | public static void test() {
39 | AddController addController = new AddController();
40 | ContactController contactController = new ContactController();
41 |
42 | //代理方把代理对象传给委托方
43 | addController.mDataInterface = contactController;
44 | addController.addEvent();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
16 |
21 |
26 |
31 |
36 |
41 |
46 |
51 |
56 |
61 |
66 |
71 |
76 |
81 |
86 |
91 |
96 |
101 |
106 |
111 |
116 |
121 |
126 |
131 |
136 |
141 |
146 |
151 |
156 |
161 |
166 |
171 |
172 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ydstar/DesignPattern/42f77a4807b058ed5e5f4365e736809d88061cc3/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ydstar/DesignPattern/42f77a4807b058ed5e5f4365e736809d88061cc3/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ydstar/DesignPattern/42f77a4807b058ed5e5f4365e736809d88061cc3/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ydstar/DesignPattern/42f77a4807b058ed5e5f4365e736809d88061cc3/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ydstar/DesignPattern/42f77a4807b058ed5e5f4365e736809d88061cc3/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ydstar/DesignPattern/42f77a4807b058ed5e5f4365e736809d88061cc3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ydstar/DesignPattern/42f77a4807b058ed5e5f4365e736809d88061cc3/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ydstar/DesignPattern/42f77a4807b058ed5e5f4365e736809d88061cc3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ydstar/DesignPattern/42f77a4807b058ed5e5f4365e736809d88061cc3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ydstar/DesignPattern/42f77a4807b058ed5e5f4365e736809d88061cc3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MyDesignPattern
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/com/yadong/pattern/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.yadong.pattern;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.1.4'
11 |
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ydstar/DesignPattern/42f77a4807b058ed5e5f4365e736809d88061cc3/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jun 25 11:01:47 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------