主要是对前面的设计模式进行一个总结,主要掌握以下十大设计模式,其他的设计模式后面的在慢慢熟悉。
public class Hungry {
//1.创建一个静态实例对象
private static Hungry instance = new Hungry();
//2. 私有化构造方法
private Hungry() {}
//3.在静态方法中创建实例对象,并将其返回
public static Hungry getInstance() {
return instance;
}
}
package com.technologystatck.designpattern.modereview.singleton;
public class Lazy {
//1.创建一个静态实例对象,允许为空
private static Lazy instance = null;
//2.私有化构造方法
private Lazy() {
}
//3.在静态方法中实例化对象,并将其返回
public static Lazy getInstance() {
if (instance == null) {
instance = new Lazy();
}
return instance;
}
//4.若为线程安全可以使用synchronized关键字
public static synchronized Lazy getSynInstance() {
if (instance == null) {
instance = new Lazy();
}
return instance;
}
}
package com.technologystatck.designpattern.modereview.singleton;
public class DoubleCheckLocking {
//1.创建实例对象
private static volatile DoubleCheckLocking instance=null;
//2.私有化构造方法
private DoubleCheckLocking(){
}
//3.使用静态方法中创建对象
public static DoubleCheckLocking getInstance(){
//先判断实例是否存在
if(instance == null){
//加锁创建实例
synchronized (DoubleCheckLocking.class){
//再次判断,若拿了锁很有可能出现还没来得及初始化就释放了锁
//导致可能创建多个实例对象
if(instance == null){
instance = new DoubleCheckLocking();
}
}
}
return instance;
}
}
使用volatile关键字修饰instance变量
private static volatile DoubleCheckLocking instance=null;
package com.technologystatck.designpattern.modereview.singleton;
public class StaticInner {
//1.通过静态内部类实例化对象
private static class StaticInnerSingleton{
private static StaticInner instance = new StaticInner();
}
//2.私有化构造方法
private StaticInner(){
}
//3.创建静态方法返回实例化的对象
public static StaticInner getInstance(){
return StaticInnerSingleton.instance;
}
}
package com.technologystatck.designpattern.modereview.singleton;
enum Enums {
//创建枚举类的实例
INSTANCE;
//对单例对象的进行相关操作的方法
public void doSingleton(){
System.out.println("正在执行枚举类实现的单例对象的方法");
}
}
package com.technologystatck.designpattern.modereview.singleton;
public class ThreadLocals {
//1.初始化ThreadLocal,同时实例化对象
private static ThreadLocal threadInstance = new ThreadLocal();
private static ThreadLocals instance=null;
//2.使用静态方法将实例化的对象返回
public static ThreadLocals getInstance(){
if(threadInstance.get()==null){
createInstance();
}
return instance;
}
//3.创建实例化对象的方法
private static final void createInstance(){
synchronized (ThreadLocals.class){
if(instance==null){
instance=new ThreadLocals();
}
}
//设置非空值,以便后续判断不再执行创建操作
threadInstance.set(threadInstance);
}
//4.调用remove方法清除当前线程的threadInstance变量的值
public static void remove(){
threadInstance.remove();
}
}
小明想要购买一套房子,他决定寻求一家房屋中介来帮助他找到一个面积超过100平方米的房子,只有符合条件的房子才会被传递给小明查看。
package com.technologystatck.designpattern.modereview.proxy;
public class StaticProxy {
public static void main(String[] args) {
House house1 = new House("武汉", 101);
House house2 = new House("上海", 201);
House house3 = new House("天津", 81);
House house4 = new House("深圳", 88);
HouseProxy houseProxy = new HouseProxy();
houseProxy.tradeHouse(house1);
houseProxy.tradeHouse(house2);
houseProxy.tradeHouse(house3);
houseProxy.tradeHouse(house4);
}
}
//1.定义抽象接口
//房屋交易接口
interface HouseTransaction{
//定义交易房子的方法
void tradeHouse(House house);
}
//2.定义被代理对象
class Seller implements HouseTransaction{
@Override
public void tradeHouse(House house) {
System.out.println("我是卖家,我在"+house.getAddress()+"卖"+house.getArea()+"平房子");
}
}
//3.定义代理对象
//相当于房屋中介
class HouseProxy implements HouseTransaction{
@Override
public void tradeHouse(House house) {
if(house.getArea()>100){
System.out.println("我是小明委托的中介,我在"+house.getAddress()+"看"+house.getArea()+"平房子");
}
}
}
//定义房子类
class House{
private String address;
private int area;
public House() {
}
public House(String address, int area) {
this.address = address;
this.area = area;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getArea() {
return area;
}
public void setArea(int area) {
this.area = area;
}
@Override
public String toString() {
return "House{" +
"address='" + address + '\'' +
", area=" + area +
'}';
}
}
ClassLoader loader
:指定当前目标对象使用类加载器,获取加载器的方法是固定的。Class>[] interfaces
:目标对象实现的接口的类型,使用泛型方式确认类型。InvocationHandler h
:事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入小明想要购买一套房子,他决定寻求一家房屋中介来帮助他找到一个面积超过100平方米的房子,只有符合条件的房子才会被传递给小明查看。买房还需要一些手续,他需要房屋中介来帮助他履行完这些手续。
package com.technologystatck.designpattern.modereview.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
public class StaticProxy {
public static void main(String[] args) {
House house1 = new House("北京", 101);
House house2 = new House("上海", 201);
House house3 = new House("广州", 81);
House house4 = new House("深圳", 88);
ArrayList<House> houses = new ArrayList<>();
houses.add(house1);
houses.add(house2);
houses.add(house3);
houses.add(house4);
HouseProxy houseProxy=null;
for (House house : houses) {
HouseTransaction target = new Seller();
HouseTransaction proxy = (HouseTransaction) new HouseProxy(target).getProxy();
if(house.getArea()>100){
proxy.tradeHouse(house);
proxy.serviceCharges(house);
}
}
}
}
//1.定义抽象接口
//房屋交易接口
interface HouseTransaction{
//定义交易房子的方法
void tradeHouse(House house);
void serviceCharges(House house);
}
//2.定义被代理对象
class Seller implements HouseTransaction{
@Override
public void tradeHouse(House house) {
System.out.println("有一个"+house.getAddress()+"的"+house.getArea()+"平房子");
}
@Override
public void serviceCharges(House house) {
System.out.println("可以交接"+house.getAddress()+"的"+house.getArea()+"平房子手续");
}
}
//3.定义代理对象
//相当于房屋中介
class HouseProxy{
private Object target;
public HouseProxy(Object o) {
this.target = o;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
//使用Proxy.newProxyInstance方法生成代理对象,
//实现InvocationHandler中的 invoke方法,
//在invoke方法中通过反射调用代理类的方法,并提供增强方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("House Proxy动态代理");
Object invoke = method.invoke(target, args);
return invoke;
}
});
}
}
//定义房子类
class House{
private String address;
private int area;
public House() {
}
public House(String address, int area) {
this.address = address;
this.area = area;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getArea() {
return area;
}
public void setArea(int area) {
this.area = area;
}
@Override
public String toString() {
return "House{" +
"address='" + address + '\'' +
", area=" + area +
'}';
}
}
优点:不需要实现接口,但是目标对象需要实现接口
package com.technologystatck.designpattern.modereview.proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class CglibProxy {
public static void main(String[] args) {
House house1 = new House("北京", 101);
House house2 = new House("上海", 201);
House house3 = new House("广州", 81);
House house4 = new House("深圳", 88);
ArrayList<House> houses = new ArrayList<>();
houses.add(house1);
houses.add(house2);
houses.add(house3);
houses.add(house4);
for (House house : houses) {
HouseTransaction proxyInstance = (HouseTransaction) new HouseProxy().getProxyInstance(Seller.class);
if(house.getArea()>100){
proxyInstance.tradeHouse(house);
proxyInstance.serviceCharges(house);
}
}
}
}
//1.定义抽象接口
//房屋交易接口
interface HouseTransaction{
//定义交易房子的方法
void tradeHouse(House house);
void serviceCharges(House house);
}
//2.定义被代理对象
class Seller implements HouseTransaction{
@Override
public void tradeHouse(House house) {
System.out.println("有一个"+house.getAddress()+"的"+house.getArea()+"平房子");
}
@Override
public void serviceCharges(House house) {
System.out.println("可以交接"+house.getAddress()+"的"+house.getArea()+"平房子手续");
}
}
//3.定义代理对象
//相当于房屋中介
class HouseProxy implements MethodInterceptor {
//给目标对象创建一个代理对象
public Object getProxyInstance(Class c){
//1.工具类
Enhancer enhancer = new Enhancer();
//2.设置父类
enhancer.setSuperclass(c);
//3.设置回调函数
enhancer.setCallback(this);
//4.创建子类(代理对象)
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Cglib代理处理");
Object object = methodProxy.invokeSuper(o, objects);
return object;
}
}
//定义房子类
class House{
private String address;
private int area;
public House() {
}
public House(String address, int area) {
this.address = address;
this.area = area;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getArea() {
return area;
}
public void setArea(int area) {
this.area = area;
}
@Override
public String toString() {
return "House{" +
"address='" + address + '\'' +
", area=" + area +
'}';
}
}
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
小明购买了一台新电脑,该电脑使用 TypeC 接口,他已经有了一个USB接口的充电器和数据线,为了确保新电脑可以使用现有的USB接口充电器和数据线,他购买了一个TypeC到USB的扩展坞。使用适配器模式设计并实现这个扩展坞系统,确保小明的新电脑既可以通过扩展坞使用现有的USB接口充电线和数据线,也可以使用TypeC接口充电。
package com.technologystatck.designpattern.modereview.adapter;
public class ClassAdapter {
public static void main(String[] args) {
//实例化适配器,相当于就可以通过适配器完成两种接口充电
AdapterCharge adapterCharge = new AdapterCharge();
adapterCharge.chargeUseUSB();
adapterCharge.chargeUseTypeC();
}
}
//定义一个期望获得的功能接口
interface TypeCTarget{
//使用TypeC接口充电
void chargeUseTypeC();
}
//定义现有的USB接口
interface USBTarget{
//使用USB接口充电
void chargeUseUSB();
}
//现有的接口具体实现类,USB
class ConcreteUSBTarget implements USBTarget{
@Override
public void chargeUseUSB() {
System.out.println("正在通过USB接口充电");
}
}
//类适配器,相当于TypeC到USB充电的扩展坞
//继承现有接口来完成对现有接口的扩展
class AdapterCharge extends ConcreteUSBTarget implements TypeCTarget{
//完成USB接口充电
@Override
public void chargeUseUSB() {
super.chargeUseUSB();
}
//完成TypeC接口充电
@Override
public void chargeUseTypeC() {
System.out.println("可以使用TypeC接口充电");
}
}
定义期望获得的功能接口,完成扩展
定义现有的接口,也就是需要被适配的接口
定义现有接口的具体实现类,需要实现现有接口
定义一个类适配器,通过继承现有接口,
持有现有接口类一个实例,并完成其扩展功能,以此来实现目标接口
package com.technologystatck.designpattern.modereview.adapter;
public class ObjectAdapter {
public static void main(String[] args) {
USBTarget concreteUSBTarget = new ConcreteUSBTarget();
AdapterCharge adapterCharge = new AdapterCharge(concreteUSBTarget);
adapterCharge.chargeUseTypeC();
}
}
//定义一个期望获得的功能接口--使用TypeC接口充电
interface TypeCTarget{
//使用TypeC接口充电
void chargeUseTypeC();
}
//定义现有的USB接口
interface USBTarget{
//使用USB接口充电
void chargeUseUSB();
}
//现有的接口具体实现类,USB
class ConcreteUSBTarget implements USBTarget{
@Override
public void chargeUseUSB() {
System.out.println("正在通过USB接口充电");
}
}
//类适配器,相当于TypeC到USB充电的扩展坞
//继承现有接口来完成对现有接口的扩展,持有实例完成扩展功能
class AdapterCharge implements TypeCTarget{
private USBTarget usbTarget;
public AdapterCharge() {
}
public AdapterCharge(USBTarget usbTarget) {
this.usbTarget = usbTarget;
}
//在现有功能的基础上扩展功能
@Override
public void chargeUseTypeC() {
usbTarget.chargeUseUSB();
System.out.println("可以使用TypeC接口充电");
}
}
小明所在的公司请假需要在OA系统上发布申请,整个请求流程包括多个处理者,每个处理者负责处理不同范围的请假天数,如果一个处理者不能处理请求,就会将请求传递给下一个处理者,请你实现责任链模式,可以根据请求天数找到对应的处理者。
审批责任链由主管(Supervisor), 经理(Manager)和董事(Director)组成,他们分别能够处理3天、7天和10天的请假天数。如果超过10天,则进行否决。
package com.technologystatck.designpattern.modereview.chainofresponsibility;
public class Chain {
public static void main(String[] args) {
Request requestObject1 = new Request("张三","病假",3);
Request requestObject2 = new Request("李四","公假",6);
Request requestObject3 = new Request("王五","事假",9);
Request requestObject4 = new Request("赵六","事假",12);
//定义责任链对象
Supervisor supervisor = new Supervisor();
Manager manager = new Manager(supervisor);
Director director = new Director(manager);
//执行
supervisor.handlerRequest(requestObject1);
manager.handlerRequest(requestObject2);
director.handlerRequest(requestObject3);
director.handlerRequest(requestObject4);
}
}
//定义请求对象
class Request{
//请求人
String name;
//请求事件
String requestStr;
//请求天数
int day;
public Request(String name, String requestStr, int day) {
this.name = name;
this.requestStr = requestStr;
this.day = day;
}
public String getName() {
return name;
}
public String getRequestStr() {
return requestStr;
}
public int getDay() {
return day;
}
}
//定义抽象处理者
interface CurrentHandler{
//设置处理当前请求的方法
void handlerRequest(Request request);
}
//定义具体处理者-主管
class Supervisor implements CurrentHandler{
//设置条件天数
private static final int APPROVE_DAY=3;
//设置下一个处理者
private CurrentHandler nextHandler;
public Supervisor() {
}
public Supervisor(CurrentHandler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handlerRequest(Request request) {
if(request.getDay()<=APPROVE_DAY){
System.out.println(request.getName()+" Approved by Supervisor.");
}else if(nextHandler !=null){
nextHandler.handlerRequest(request);
}else{
System.out.println(request.getName()+" No Approve by Supervisor.");
}
}
}
//定义具体处理者-主管
class Manager implements CurrentHandler{
//设置条件天数
private static final int APPROVE_DAY=7;
//设置下一个处理者
private CurrentHandler nextHandler;
public Manager(CurrentHandler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handlerRequest(Request request) {
if(request.getDay()<=APPROVE_DAY){
System.out.println(request.getName()+" Approved by Manager.");
}else if(nextHandler !=null){
nextHandler.handlerRequest(request);
}else{
System.out.println(request.getName()+" No Approve by Manager.");
}
}
}
//定义具体处理者-董事
class Director implements CurrentHandler{
//设置条件天数
private static final int APPROVE_DAY=10;
//设置下一个处理者
private CurrentHandler nextHandler;
public Director(CurrentHandler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handlerRequest(Request request) {
if(request.getDay()<=APPROVE_DAY){
System.out.println(request.getName()+" Approved by Director.");
}else if(nextHandler !=null){
nextHandler.handlerRequest(request);
}else{
System.out.println(request.getName()+" No Approve by Director.");
}
}
}
小明家有两个工厂,一个用于生产圆形积木,一个用于生产方形积木,请你帮他设计一个积木工厂系统,记录积木生产的信息。
package com.technologystatck.designpattern.modereview.simplefactory;
import java.util.ArrayList;
import java.util.List;
public class SimpleFactory {
public static void main(String[] args) {
BlockFactorySystem blockFactorySystem = new BlockFactorySystem();
blockFactorySystem.BuildBlocks("redirect",2);
blockFactorySystem.BuildBlocks("square",2);
//创建圆形
BlockFactory.factoryCreateBlock("redirect").createBlock();
//创建方形
BlockFactory.factoryCreateBlock("square").createBlock();
}
}
//定义抽象产品类
abstract class Product{
//创建积木方法
abstract void createBlock();
}
//定义具体产品类--圆形积木
class RedirectBlock extends Product{
@Override
void createBlock() {
System.out.println("创建圆形积木");
}
}
//定义具体产品类--方形积木
class SquareBlock extends Product{
@Override
void createBlock() {
System.out.println("创建方形积木");
}
}
//定义工厂类
class BlockFactory{
public static Product factoryCreateBlock(String type){
if(type.equals("redirect")){
return new RedirectBlock();
}else if(type.equals("square")){
return new SquareBlock();
}else{
throw new IllegalArgumentException("无效的积木");
}
}
}
//积木工厂系统
class BlockFactorySystem{
//定义集合存放积木信息
private List<Product> products=new ArrayList();
//创建积木方法
public void BuildBlocks(String type,int nums){
for(int i=0;i<nums;i++){
if(type.equals("redirect") || type.equals("square"))
BlockFactory.factoryCreateBlock(type).createBlock();
}
}
}
小明家有两个工厂,一个用于生产圆形积木,一个用于生产方形积木,请你帮他设计一个积木工厂系统,记录积木生产的信息。
package com.technologystatck.designpattern.modereview.factorymethod;
import java.util.ArrayList;
import java.util.List;
public class FactoryMethod {
public static void main(String[] args) {
new BlockFactorySystem().BuildBlocks(new RedirectBlockFactory(),3);
new BlockFactorySystem().BuildBlocks(new SquareBlockFactory(),2);
System.out.println("=====================");
RedirectBlockFactory redirectBlockFactory = new RedirectBlockFactory();
redirectBlockFactory.createBlock().createBlockProduct();
BlockProduct block = new SquareBlockFactory().createBlock();
block.createBlockProduct();
}
}
//定义抽象产品接口
interface BlockProduct{
void createBlockProduct();
}
//定义具体产品实现类-圆形积木
class RedirectBlock implements BlockProduct{
@Override
public void createBlockProduct() {
System.out.println("创建圆形积木");
}
}
//定义具体产品实现类-方形积木
class SquareBlock implements BlockProduct{
@Override
public void createBlockProduct() {
System.out.println("创建方形积木");
}
}
//定义抽象工厂接口
interface BlockFactory{
//创建积木
BlockProduct createBlock();
}
//定义具体工厂实现类-圆形积木
class RedirectBlockFactory implements BlockFactory{
@Override
public BlockProduct createBlock() {
return new RedirectBlock();
}
}
//定义具体工厂实现类-方形积木
class SquareBlockFactory implements BlockFactory{
@Override
public BlockProduct createBlock() {
return new SquareBlock();
}
}
//定义工厂系统
class BlockFactorySystem{
private List<BlockProduct> blockProducts=new ArrayList<BlockProduct>();
public void BuildBlocks(BlockFactory factory,int nums){
for(int i=0;i<nums;i++){
BlockProduct block = factory.createBlock();
blockProducts.add(block);
block.createBlockProduct();
}
}
}
定义一个抽象模板类,负责给出算法的轮廓和骨架,由一个模板方法和若干个基本方法构成
定义模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法
定义基本方法,是实现算法各个步骤的方法,是模板方法的组成部分
抽象方法:由抽象类声明、由其具体子类实现
具体方法:由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承
钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种
用于判断的逻辑方法,方法名一般为isXxx,返回值类型为boolean类型
可以定义多个具体模板类,实现抽象模板类中所定义的抽象方法和钩子方法,是顶级逻辑的组成步骤
小明喜欢品尝不同类型的咖啡,她发现每种咖啡的制作过程有一些相同的步骤,他决定设计一个简单的咖啡制作系统,使用模板方法模式定义咖啡的制作过程。系统支持两种咖啡类型:美式咖啡(American Coffee)和拿铁(Latte)。
咖啡制作过程包括以下步骤:
其中,美式咖啡和拿铁的调料添加方式略有不同, 拿铁在添加调料时需要添加牛奶Adding milk
package com.technologystatck.designpattern.modereview.template;
public class Template {
public static void main(String[] args) {
CoffeeTemplate american = new American();
CoffeeTemplate latte = new Latte();
CoffeeTemplate milk = new Milk();
//通过钩子方法进行判断
if (!american.isMilk()) {
american.makeCoffee();
}
if (!latte.isMilk()) {
latte.makeCoffee();
}
if (!milk.isMilk())
milk.makeMilk();
}
}
abstract class CoffeeTemplate {
//咖啡名称
private String coffeeName;
//构造函数
public CoffeeTemplate(String coffeeName) {
this.coffeeName = coffeeName;
}
//定义制造咖啡的模板方法
final void makeCoffee() {
System.out.println("making " + coffeeName + ": ");
grindingCoffeeBeans();
brewingCoffee();
addingCondiments();
}
//定义制造牛奶的模板方法
final void makeMilk() {
System.out.println("making " + coffeeName + ": ");
addingCondiments();
}
//定义实现模板方法的基本方法
//研磨方法
void grindingCoffeeBeans() {
System.out.println("研磨咖啡豆");
}
//冲泡咖啡
void brewingCoffee() {
System.out.println("冲泡咖啡");
}
//添加调料根据咖啡的种类,调料不一样
//定义基本方法中的抽象方法
abstract void addingCondiments();
//定义钩子方法,判断是否是牛奶,牛奶不需要添加其他
boolean isMilk() {
return false;
}
}
//定义美式咖啡具体实现类
class American extends CoffeeTemplate {
public American() {
super("American Coffee");
}
@Override
void addingCondiments() {
System.out.println("添加American Coffee的调料");
}
}
//定义拿铁咖啡具体实现类
class Latte extends CoffeeTemplate {
public Latte() {
super("Latte Coffee");
}
@Override
void addingCondiments() {
System.out.println("添加Latte Coffee的调料");
}
}
//定义牛奶具体实现类,但是需要判断是否是牛奶
class Milk extends CoffeeTemplate {
public Milk() {
super("Milk");
}
@Override
void addingCondiments() {
System.out.println("牛奶不需要添加调料");
}
@Override
boolean isMilk() {
System.out.println("是牛奶,不需要添加调料");
return true;
}
}
小明喜欢品尝不同口味的咖啡,他发现每种咖啡都可以加入不同的调料,比如牛奶、糖和巧克力。他决定使用装饰者模式制作自己喜欢的咖啡。
请设计一个简单的咖啡制作系统,使用装饰者模式为咖啡添加不同的调料。系统支持两种咖啡类型:黑咖啡(Black Coffee)和拿铁(Latte)。
package com.technologystatck.designpattern.modereview.decorator;
public class Decorator {
public static void main(String[] args) {
CoffeeComponent latteCoffee = new LatteCoffee();
CoffeeComponent blackCoffee = new BlackCoffee();
latteCoffee.makeCoffee();
blackCoffee.makeCoffee();
System.out.println("====================");
new Milk(latteCoffee).makeCoffee();
new Sugar(blackCoffee).makeCoffee();
}
}
//定义抽象构件
abstract class CoffeeComponent{
//需要添加的调料名字
private String seasoning;
public CoffeeComponent() {
}
//可以自己手动传参
public CoffeeComponent(String seasoning) {
this.seasoning = seasoning;
}
public String getSeasoning() {
return seasoning;
}
public void setSeasoning(String seasoning) {
this.seasoning = seasoning;
}
//制作咖啡的方法
abstract void makeCoffee();
}
//定义具体构件
//黑咖啡的制作
class BlackCoffee extends CoffeeComponent{
public BlackCoffee() {
super("黑咖啡浓缩原液");
}
@Override
void makeCoffee() {
System.out.println("making "+super.getSeasoning()+" black coffee");
}
}
//拿铁的制作
class LatteCoffee extends CoffeeComponent{
public LatteCoffee() {
super("拿铁咖啡浓缩原液");
}
@Override
void makeCoffee() {
System.out.println("making "+super.getSeasoning()+" latte coffee");
}
}
//定义抽象装饰
abstract class CoffeeDecorator extends CoffeeComponent{
//实例化抽象构件
private CoffeeComponent coffeeComponent;
public CoffeeComponent getCoffeeComponent() {
return coffeeComponent;
}
public void setCoffeeComponent(CoffeeComponent coffeeComponent) {
this.coffeeComponent = coffeeComponent;
}
//默认构造方法
public CoffeeDecorator(String seasoning, CoffeeComponent coffeeComponent) {
super(seasoning);
this.coffeeComponent = coffeeComponent;
}
}
//定义具体装饰
//黑咖啡具体装饰类
class Milk extends CoffeeDecorator{
public Milk(CoffeeComponent coffeeComponent) {
//添加额外的操作
//添加半杯奶
super("半杯奶", coffeeComponent);
}
@Override
void makeCoffee() {
System.out.println("制作"+super.getSeasoning()+"的黑咖啡");
}
}
class Sugar extends CoffeeDecorator{
//添加额外的操作
//添加两勺糖
public Sugar( CoffeeComponent coffeeComponent) {
super("两勺糖", coffeeComponent);
}
@Override
void makeCoffee() {
System.out.println("添加了"+super.getSeasoning()+"的拿铁");
}
}
小明所在的学校有一个时钟(主题),每到整点时,它就会通知所有的学生(观察者)当前的时间,请你使用观察者模式实现这个时钟通知系统。
注意点:时间从 0 开始,并每隔一个小时更新一次。
package com.technologystatck.designpattern.modereview.observer;
import java.util.ArrayList;
import java.util.List;
public class ClockObserver {
public static void main(String[] args) {
Clock clock = new Clock();
ConcreteObserver concreteObserver1 = new ConcreteObserver("张三");
ConcreteObserver concreteObserver2 = new ConcreteObserver("李四");
ConcreteObserver concreteObserver3 = new ConcreteObserver("王五");
//注册三个新用户
clock.register(concreteObserver1);
clock.register(concreteObserver2);
clock.register(concreteObserver3);
//通知方法通知所有的人
clock.notifys("正在注册新用户");
//提供注销用户
clock.removes(concreteObserver2);
//通知方法通知所有的人
clock.notifys("正在注销用户"+concreteObserver2.getName());
for(int i=0,updates=3;i<updates;i++){
clock.tick();
}
}
}
//定义抽象主题
interface Subject{
//增加订阅者
void register(Observer observer);
//删除订阅者
void removes(Observer observer);
//通知订阅者
void notifys(String messages);
}
//定义具体主题
class Clock implements Subject{
//存储所有的用户
private List<Observer> observers=new ArrayList<>();
private int hour=0;
@Override
public void register(Observer observer) {
observers.add(observer);
}
@Override
public void removes(Observer observer) {
observers.remove(observer);
}
@Override
public void notifys(String messages) {
for (Observer observer : observers) {
//调用更新方法通知全局
observer.update(messages);
}
}
//定义方法 模拟时钟
public void tick(){
hour=(hour+1)%24;
//通知时间
notifys("现在时间: "+hour);
}
}
//定义抽象观察者
interface Observer{
void update(String messages);
}
//定义具体观察者
class ConcreteObserver implements Observer{
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void update(String messages) {
System.out.println(this.name+" --> "+messages);
}
}
小明家的超市推出了不同的购物优惠策略,你可以根据自己的需求选择不同的优惠方式。其中,有两种主要的优惠策略:
具体的满减规则如下:
满100元减5元
满150元减15元
满200元减25元
满300元减40元
请你设计一个购物优惠系统,用户输入商品的原价和选择的优惠策略编号,系统输出计算后的价格。
package com.technologystatck.designpattern.modereview.strategy;
public class Strategy {
public static void main(String[] args) {
DiscountContext discountContext = new DiscountContext();
DiscountStrategy9 discountStrategy9 = new DiscountStrategy9();
DiscountStrategyFull discountStrategyFull = new DiscountStrategyFull();
// discountContext.setStrategy(discountStrategy9);
discountContext.setStrategy(discountStrategyFull);
int price = discountContext.applyDiscount(120);
System.out.println("折扣后的价格"+price);
}
}
//定义抽象策略类
interface DiscountStrategy {
//定义算法方法
int applyDiscount(int originalPrice);
}
//定义具体策略类
//定义九折优惠策略类
class DiscountStrategy9 implements DiscountStrategy {
@Override
public int applyDiscount(int originalPrice) {
return (int) (originalPrice * 0.9); //返回九折优惠后的价格(保留两位小数)
}
}
//定义满减优惠策略类
class DiscountStrategyFull implements DiscountStrategy {
//定义满足的价格
private int[] thresholds={100,150,200,300};
//定义满减的价格
private int[] discounts={5,15,25,40};
@Override
public int applyDiscount(int originalPrice) {
//先遍历满足的价格
for(int i=thresholds.length-1;i>=0;i--){
//若价格有大于或等于满足价格中
//从最高的价格开始遍历,若有,则返回满减价格
//例如,如果大于300,则因为从后开始遍历,所以满减的价格也是从后开始遍历,则是减去40
if(originalPrice>=thresholds[i]){
//返回满减价格
return originalPrice-discounts[i];
}
}
//若价格小于满足价格数组,则返回原价
return originalPrice;
}
}
//定义上下文类
class DiscountContext {
private DiscountStrategy strategy;
//设置方法
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
//输入原价格
//通过该类来调用折扣方法,进行价格折扣
public int applyDiscount(int orignalPrice) {
return strategy.applyDiscount(orignalPrice);
}
}