├── .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 |