这篇内容是从另一篇:UML建模、设计原则 中分离出来的,原本这个创建型设计模式是和其放在一起的
但是:把这篇创建型设计模式放在一起让我贼别扭,看起来贼不舒服,越看念头越不通达,导致老衲躺在床上脑海中冒出来时都睡不着了
因此:最后实在受不了了,还是将其抽离出来
分类:

注:使用设计模式的规范,类名 = 需求名+使用的对应设计模式名,如:StringBuilder,这就是使用了Builder建造者模式
设计模式不是一成不变的,主要是思想,至于形不需要在意,形只是便于理解罢了
若是想要知道Java什么地方用到了对应模式,那就去Spring中直接全局搜索模式的名字,就会出来一堆的实现类,Spring中基本涵盖了所有设计模式
这个类型的模式是专门针对于创建对象的,也就是它的适用机制
换言之:这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象
定义:保证对象全局唯一,即:保证一个类只有一个实例,哪怕是多线程来进行访问,向外提供一个访问此实例的方法即可
使用场景
package com.zixieqing.o1static;
import java.util.HashMap;
import java.util.Map;
/**
* <p>@description : 该类功能 使用static的方式</p>
* <p>@package : com.zixieqing.o1static</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class StaticSingleton {
private static Map<String, String> CACHE = new HashMap<>();
}
定义:体现在一个“懒”字上,即:需要时才去创建对象
package com.zixieqing.o2lazy;
/**
* <p>@description : 该类功能 懒汉式
* 此种方式不安全:好比多个人抢厕所,会造成不安全,可能有多个人抢到
* </p>
* <p>@package : com.zixieqing.o2lazy</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class LazySingleton {
/**
* 1、private static 当前类的属性
*/
private static LazySingleton LAZY_SINGLETON_INSTANCE;
/**
* 2、private 的构造
*/
private LazySingleton() {
}
/**
* 3、提供public static 创建当前类的对象的方法
*/
public static LazySingleton getInstance() {
if (null != LAZY_SINGLETON_INSTANCE) return LAZY_SINGLETON_INSTANCE;
LAZY_SINGLETON_INSTANCE = new LazySingleton();
return LAZY_SINGLETON_INSTANCE;
}
/**
* 4、要想稍微安全就加synchronized同步锁
* 但是:此种方式因为把synchronized加在了方法上,导致所有访问争锁而出现 资源的浪费
*/
/* public static synchronized lazy_unsafe_singleton getInstance() {
if (null != LAZY_UNSAFE_INSTANCE_SINGLETON) return LAZY_UNSAFE_INSTANCE_SINGLETON;
LAZY_UNSAFE_INSTANCE_SINGLETON = new Singleton_lazy_unsafe();
return LAZY_UNSAFE_INSTANCE_SINGLETON;
}*/
}
定义:体现在“饿”字上,即:一开始就初始化
package com.zixieqing.o3hunger;
/**
* <p>@description : 该类功能 饿汉式实现
* 这种方式和利用static的方式是异曲同工的
* </p>
* <p>@package : com.zixieqing.o3hunger</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class HungerSingleton {
private static HungerSingleton HUNGER_SINGLETON_INSTANCE = new HungerSingleton();
private HungerSingleton() {}
/**
* 这种方式其实也不安全
* 因为当多线程在if判断时如果在同一时刻二者都判断成立为null,就会创建不同的实例
*/
public static HungerSingleton getInstance() {
if (null != HUNGER_SINGLETON_INSTANCE) return HUNGER_SINGLETON_INSTANCE;
HUNGER_SINGLETON_INSTANCE = new HungerSingleton();
return HUNGER_SINGLETON_INSTANCE;
}
}
package com.zixieqing.o4innerclass;
/**
* <p>@description : 该类功能 使用内部类实现 - 推荐的一种</p>
* <p>@package : com.zixieqing.o4innerclass</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class InnerClassSingleton {
/**
* 1、private的构造
*/
private InnerClassSingleton() {}
/**
* 2、private static的内部类
* 巧妙之处:使用static修饰,则:做到线程安全,也巧妙借助了第一种实现方式:使用static的形式
* 同时:内部类可以访问外部类的静态属性和静态方法
*/
private static class NewInstance{
public static InnerClassSingleton INSTANCE = new InnerClassSingleton();
}
/**
* 3、public static对外提供获取当前类实例的方法
*/
public static InnerClassSingleton getInstance() {
return NewInstance.INSTANCE;
}
}
package com.zixieqing.o5twinlock;
/**
* <p>@description : 该类功能 双重锁校验(线程安全)</p>
* <p>@package : com.zixieqing.o5twinlock</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class TwinLockSingleton {
/**
* 最好加上volatile关键字,它的作用是:不进行指令重排(指令重排是JVM中的)
*/
private static volatile TwinLockSingleton INSTANCE;
private TwinLockSingleton() {}
public static TwinLockSingleton getInstance() {
if (null != INSTANCE) return INSTANCE;
// 双重验证:synchronized 和 if
synchronized (TwinLockSingleton.class) {
if (null == INSTANCE) return INSTANCE = new TwinLockSingleton();
}
return INSTANCE;
}
}
package com.zixieqing.o6cas;
import java.util.concurrent.atomic.AtomicReference;
/**
* <p>@description : 该类功能 利用CAS算法实现
* 好处:CAS的忙等算法是靠底层硬件,所以:保证了线程安全 和 不会产生线程的切换和阻塞的开销,从而提高性能
* 并且:可以支持较大的并发性
* </p>
* <p>@package : com.zixieqing.o6cas</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class CASSingleton {
private static CASSingleton CAS_SINGLETON_INSTANCE;
/**
* AtomicReference<K> 原子引用 保存“一个”K实例
*/
private static final AtomicReference<CASSingleton> INSTANCE = new AtomicReference<>();
public static CASSingleton getInstance() {
/*
缺点就在这里:CAS的忙等 从而造成:如果一直没有获取就会处于死循坏当中
*/
for (;;) {
CAS_SINGLETON_INSTANCE = INSTANCE.get();
if (null != CAS_SINGLETON_INSTANCE) return CAS_SINGLETON_INSTANCE;
/*
boolean compareAndSet(V expect, V update)
expect 预期值
update 要改成的新值
如果当前值和预期值相等,那么就以原子的方式将值改为新值
下列逻辑:期望INSTANCE是null,所以将INSTANCE的值改为new Singleton_CAS()
*/
INSTANCE.compareAndSet(null, new CASSingleton());
// 获取INSTANCE的值 返回值就是AtomicReference<Singleton_CAS>中的泛型类型
return INSTANCE.get();
}
}
}
package com.zixieqing.o7num;
/**
* <p>@description : 该类功能 使用枚举来实现(极度推荐)
* </p>
* <p>@package : com.zixieqing.o7num</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public enum EnumSingleton {
/**
* 对象
*/
INSTANCE;
/**
* 根据需要自行配置getter也行
*/
}
定义:根据一个已有对象(原型实例) 创建 新的对象(就是克隆)
解决的问题:创建重复对象,而这部分对象本身比较复杂,生成过程从库或者RPC接口中获取数据的耗时时长可能会很长,因此:采用克隆的方式会节省时间,总之:当系统中需要创建相同或相似的对象时,就可以用原型模式
场景(在开发中貌似都没用到过):
ctrl+c 和 ctrl+v)Object.clone()了解两个名词:浅拷贝和深拷贝
浅拷贝会将原对象的属性值赋值给新对象(拷贝的是值)
注:String底层被final修饰了的,修改值之后是重新创建了一个Sting对象,修改之后不会影响原对象
package com.zixieqing;
/**
* <p>@description : 该类功能 原型类(属性都是基本数据类型时)
* Cloneable 标志Object.clone()方法可以对Person该类的实例进行字段的复制
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class Person implements Cloneable{
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person person = null;
try {
person = (Person) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return person;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.zixieqing;
/**
* <p>@description : 该类功能 测试
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Person person = new Person();
person.setName("紫邪情");
Person clonePerson = (Person) person.clone();
System.out.println( "原型对象:" + person);
System.out.println( "克隆对象:" + clonePerson);
clonePerson.setName("小紫");
System.out.println("==========修改之后=============");
System.out.println(person);
System.out.println(clonePerson);
}
}

package com.zixieqing;
/**
* <p>@description : 该类功能 原型类(属性是引用数据类型时)
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class Peron2 implements Cloneable{
private Person person;
public Peron2() {
}
public Peron2(Person person) {
this.person = person;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Peron2 peron2 = null;
try {
peron2 = (Peron2) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return peron2;
}
@Override
public String toString() {
return "Peron2{" +
"person=" + person +
'}';
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
package com.zixieqing;
/**
* <p>@description : 该类功能 测试
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Peron2 peron2 = new Peron2();
Person person = new Person("法外狂徒");
peron2.setPerson(person);
Peron2 clonePerson2 = (Peron2) peron2.clone();
System.out.println(peron2);
System.out.println(clonePerson2);
person.setName("张三");
clonePerson2.setPerson(person);
System.out.println("修改之后");
System.out.println(peron2);
System.out.println(clonePerson2);
}
}

package com.zixieqing.o2useserialize;
import com.zixieqing.o1useclone.Person;
import java.io.*;
/**
* <p>@description : 该类功能 测试
* </p>
* <p>@package : com.zixieqing.o2useserialize</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class Test {
public static void main(String[] args) throws IOException {
Person3 person3 = new Person3(0, new Person("紫邪情"));
Person3 cloneInstance = cloneInstance(person3);
System.out.println(person3);
System.out.println(cloneInstance);
cloneInstance.setSex(1);
System.out.println("===========修改之后=============");
System.out.println(person3);
System.out.println(cloneInstance);
}
/**
* <p>@description : 该方法功能 对象序列化克隆
* </p>
* <p>@methodName : cloneInstance</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param person3 要进行序列化克隆的对象
* @return com.zixieqing.o2useserialize.Person3
*/
private static Person3 cloneInstance(Person3 person3) throws IOException {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis;
ObjectInputStream ois;
Person3 person = null;
try {
// 序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(person3);
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
person = (Person3) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != bos) bos.close();
if (null != oos) oos.close();
}
return person;
}
}

定义:把对类的创建初始化全都交给一个工厂来执行,而用户不需要关心创建的过程是什么样的,只需要告诉工厂,我想要什么就行了
设计模式中并没有所谓的简单工厂,这玩意儿严格来说是一种编码规范,但是:也是学工厂模式的基础
简单工厂的角色
简单工厂逻辑草图

开发场景:网上买商品,假设有三种购买方式(前面的数字对应其类型):1、通过优惠卡;2、通过快播兑换卡;3、啥也没用,直接购买实物商品,根据前面说的三角色来整活
准备工作:依赖导入
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- LOGGING begin -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.9</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
1、抽象产品:定义规则
package com.zixieqing.o1simplefactory.o1simplelogic;
/**
* <p>@description : 该类功能 抽象产品:购物
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o1simplelogic</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IShopping {
/**
* <p>@description : 该方法功能 发送商品
* </p>
* <p>@methodName : sendCommodity</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param userId 用户id
* @param goodsName 商品名
*/
void sendCommodity(String userId, String goodsName) throws Exception;
}
2、具体产品:实现或继承抽象产品的子类
package com.zixieqing.o1simplefactory.o1simplelogic.impl;
import com.zixieqing.o1simplefactory.o1simplelogic.IShopping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>@description : 该类功能 具体商品:优惠卡
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o1simplelogic.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class CouponService implements IShopping {
private Logger logger = LoggerFactory.getLogger(CouponService.class);
@Override
public void sendCommodity(String userId, String goodsName) throws Exception {
logger.info("用户:{},通过优惠卡xxxxxx,购买了:{}", userId, goodsName);
}
}
package com.zixieqing.o1simplefactory.o1simplelogic.impl;
import com.zixieqing.o1simplefactory.o1simplelogic.IShopping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>@description : 该类功能 具体商品:快播兑换卡
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o1simplelogic.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class QvodCardService implements IShopping {
private Logger logger = LoggerFactory.getLogger(QvodCardService.class);
@Override
public void sendCommodity(String userId, String goodsName) throws Exception {
logger.info("用户:{},通过快播兑换卡yyyyy,购买了:{}", userId, goodsName);
}
}
package com.zixieqing.o1simplefactory.o1simplelogic.impl;
import com.zixieqing.o1simplefactory.o1simplelogic.IShopping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>@description : 该类功能 具体商品:啥也不用,直接实物购买
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o1simplelogic.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class GoodsService implements IShopping {
private Logger logger = LoggerFactory.getLogger(GoodsService.class);
@Override
public void sendCommodity(String userId, String goodsName) throws Exception {
logger.info("用户:{},实物购买了:{}", userId, goodsName);
}
}
3、产品工厂:提供创建产品的方法,让调用者通过该工厂获取产品
package com.zixieqing.o1simplefactory.o1simplelogic;
import com.zixieqing.o1simplefactory.o1simplelogic.impl.CouponService;
import com.zixieqing.o1simplefactory.o1simplelogic.impl.GoodsService;
import com.zixieqing.o1simplefactory.o1simplelogic.impl.QvodCardService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>@description : 该类功能 产品工厂:购物工厂
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o1simplelogic</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class ShoppingFactory {
private Logger logger = LoggerFactory.getLogger(ShoppingFactory.class);
/**
* <p>@description : 该方法功能 购物
* </p>
* <p>@methodName : shopping</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param type 购物方式 1、优惠卡;2、快播兑换卡;3、实物购买
* @return com.zixieqing.o1simplefactory.o1simplelogic.IShopping
*/
public IShopping shopping(Integer type) {
if (null == type) return null;
logger.info("正在拣货.....");
if (1 == type) return new CouponService();
if (2 == type) return new QvodCardService();
if (3 == type) return new GoodsService();
throw new RuntimeException("不存在的商品服务类型");
}
}
static就变成了静态工厂(静态方法能被继承、但不能被重写)4、测试:调用者通过工厂获取对应产品
package com.zixieqing;
import com.zixieqing.o1simplefactory.o1simplelogic.IShopping;
import com.zixieqing.o1simplefactory.o1simplelogic.ShoppingFactory;
/**
* <p>@description : 该类功能 测试
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class APITest {
public static void main(String[] args) throws Exception{
ShoppingFactory shoppingFactory = new ShoppingFactory();
// 1、优惠卡类型
IShopping shopping_1 = shoppingFactory.shopping(1);
shopping_1.sendCommodity(System.nanoTime()+"", "充气娃娃");
System.out.println("================华丽的分割线===================");
// 2、快播兑换卡
IShopping shopping_2 = shoppingFactory.shopping(2);
shopping_2.sendCommodity(System.nanoTime()+"", "AI女票");
System.out.println("================华丽的分割线===================");
IShopping shopping_3 = shoppingFactory.shopping(3);
shopping_3.sendCommodity(System.nanoTime()+"", "枸杞");
}
}

上面就是理解简单工厂的逻辑,总结一丢丢



1、先决条件:先简单搞个返回结果集的工具类
package com.zixieqing.o1simplefactory.o2complex.util;
/**
* <p>@description : 该类功能 返回结果集工具类
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex.util</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class ResultUtil {
/**
* 编码
*/
private String code;
/**
* 信息
*/
private String info;
public ResultUtil(String code, String info) {
this.code = code;
this.info = info;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
2、优惠卡服务
package com.zixieqing.o1simplefactory.o2complex.coupon;
import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>@description : 该类功能 模拟发放优惠券业务
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex.coupon</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class CouponService {
private Logger logger = LoggerFactory.getLogger(CouponService.class);
/**
* <p>@description : 该方法功能 发放优惠券
* </p>
* <p>@methodName : sendCoupon</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param uId 用户id
* @param couponNumber 分配的优惠券号码
* @param uuid 随机生成的uuid号
* @return com.zixieqing.o1simplefactory.o2complex.util.ResultUtil
*/
public ResultUtil sendCoupon(String uId, String couponNumber, String uuid) {
logger.info("发放优惠券业务准备启动..........");
logger.info("用户:{},获得了优惠券:{}", uId, uId + couponNumber + uuid);
return new ResultUtil("0000", "优惠券发放成功");
}
}
3、快播兑换卡业务
package com.zixieqing.o1simplefactory.o2complex.qvod;
import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>@description : 该类功能 快播兑换卡业务
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex.qvod</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class QvodService {
private Logger logger = LoggerFactory.getLogger(QvodService.class);
/**
* <p>@description : 该方法功能 授予兑换卡
* </p>
* <p>@methodName : grentToken</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param phone 用户手机号
* @param cardId 随机生成的卡号
* @return com.zixieqing.o1simplefactory.o2complex.util.ResultUtil
*/
public ResultUtil grentToken(String phone, String cardId) {
logger.info("授予的兑换卡为:{}", phone + cardId);
return new ResultUtil("0000", phone + cardId);
}
}
4、实物购买商品业务
package com.zixieqing.o1simplefactory.o2complex.goods;
/**
* <p>@description : 该类功能 实物购买:支付要求对象
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex.goods</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class DeliverRequest {
/**
* 用户姓名
*/
private String userName;
/**
* 用户手机
*/
private String userPhone;
/**
* 商品SKU:库存保有单位
*/
private String sku;
/**
* 订单ID
*/
private String orderId;
/**
* 收货人姓名
*/
private String consigneeUserName;
/**
* 收货人手机
*/
private String consigneeUserPhone;
/**
* 收获人地址
*/
private String consigneeUserAddress;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPhone() {
return userPhone;
}
public void setUserPhone(String userPhone) {
this.userPhone = userPhone;
}
public String getSku() {
return sku;
}
public void setSku(String sku) {
this.sku = sku;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getConsigneeUserName() {
return consigneeUserName;
}
public void setConsigneeUserName(String consigneeUserName) {
this.consigneeUserName = consigneeUserName;
}
public String getConsigneeUserPhone() {
return consigneeUserPhone;
}
public void setConsigneeUserPhone(String consigneeUserPhone) {
this.consigneeUserPhone = consigneeUserPhone;
}
public String getConsigneeUserAddress() {
return consigneeUserAddress;
}
public void setConsigneeUserAddress(String consigneeUserAddress) {
this.consigneeUserAddress = consigneeUserAddress;
}
}
package com.zixieqing.o1simplefactory.o2complex.goods;
import com.alibaba.fastjson.JSON;
import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>@description : 该类功能 实物购买商品业务
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex.goods</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class GoodsService {
private Logger logger = LoggerFactory.getLogger(GoodsService.class);
/**
* <p>@description : 该方法功能 发货
* </p>
* <p>@methodName : deliverGoods</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param deliverRequest 辅助:支付对象
* @return com.zixieqing.o1simplefactory.o2complex.util.ResultUtil
*/
public ResultUtil deliverGoods(DeliverRequest deliverRequest) {
logger.info("模拟发送实物商品一个:{}", JSON.toJSONString(deliverRequest));
return new ResultUtil("0000", "发货成功:" + deliverRequest);
}
}
5、抽象产品:定义规则
package com.zixieqing.o1simplefactory.o2complex;
import java.util.Map;
/**
* <p>@description : 该类功能 商品
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface ICommodityService {
/**
* <p>@description : 该方法功能 发送商品
* </p>
* <p>@methodName : sendCommodity</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param uId 用户id
* @param commodityId 商品id
* @param bizId 业务id
* @param extMap 扩展信息
*/
void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception;
}
6、具体商品:实现或继承抽象产品的子类
package com.zixieqing.o1simplefactory.o2complex.impl;
import com.zixieqing.o1simplefactory.o2complex.ICommodityService;
import com.zixieqing.o1simplefactory.o2complex.coupon.CouponService;
import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.UUID;
/**
* <p>@description : 该类功能 TODO
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class CouponCommodityServiceImpl implements ICommodityService {
private Logger logger = LoggerFactory.getLogger(CouponCommodityServiceImpl.class);
/**
* 模拟@autowried注入
*/
private CouponService couponService = new CouponService();
@Override
public void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception {
ResultUtil result = couponService.sendCoupon(uId, commodityId, UUID.randomUUID().toString());
if (!"0000".equals(result.getCode()))
throw new RuntimeException(result.getInfo());
}
}
package com.zixieqing.o1simplefactory.o2complex.impl;
import com.zixieqing.o1simplefactory.o2complex.ICommodityService;
import com.zixieqing.o1simplefactory.o2complex.qvod.QvodService;
import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
/**
* <p>@description : 该类功能 快播兑换卡发货
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class QvodCommodityServiceImpl implements ICommodityService {
private Logger logger = LoggerFactory.getLogger(CouponCommodityServiceImpl.class);
/**
* 模拟注入
*/
private QvodService qvodService = new QvodService();
@Override
public void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception {
// 这里把电话号码定死,模拟而已
ResultUtil result = qvodService.grentToken("12345678910", bizId + commodityId);
logger.info("通过快播兑换卡:{},获取商品:{}", bizId + commodityId, commodityId);
if (!"0000".equals(result.getCode()))
throw new RuntimeException(result.getInfo());
}
}
package com.zixieqing.o1simplefactory.o2complex.impl;
import com.zixieqing.o1simplefactory.o2complex.ICommodityService;
import com.zixieqing.o1simplefactory.o2complex.goods.DeliverRequest;
import com.zixieqing.o1simplefactory.o2complex.goods.GoodsService;
import com.zixieqing.o1simplefactory.o2complex.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
/**
* <p>@description : 该类功能 实物购买商品
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class GoodsCommodityServiceImpl implements ICommodityService {
private Logger logger = LoggerFactory.getLogger(GoodsCommodityServiceImpl.class);
/**
* 模拟注入
*/
private GoodsService goodsService = new GoodsService();
@Override
public void sendCommodity(String uId, String commodityId, String bizId, Map<String, String> extMap) throws Exception {
DeliverRequest deliverRequest = new DeliverRequest();
// 下面这些信息去数据库搞出来
deliverRequest.setUserName("紫邪情");
deliverRequest.setUserPhone("123143124342");
deliverRequest.setSku(commodityId);
deliverRequest.setOrderId(bizId);
deliverRequest.setConsigneeUserName(extMap.get("consigneeUserName"));
deliverRequest.setConsigneeUserPhone(extMap.get("consigneeUserPhone"));
deliverRequest.setConsigneeUserAddress(extMap.get("consigneeUserAddress"));
ResultUtil result = goodsService.deliverGoods(deliverRequest);
if (!"0000".equals(result.getCode()))
throw new RuntimeException(result.getInfo());
}
}
7、产品工厂:提供创建产品的方法,让调用者通过该方法获取产品
package com.zixieqing.o1simplefactory.o2complex;
import com.zixieqing.o1simplefactory.o2complex.impl.CouponCommodityServiceImpl;
import com.zixieqing.o1simplefactory.o2complex.impl.GoodsCommodityServiceImpl;
import com.zixieqing.o1simplefactory.o2complex.impl.QvodCommodityServiceImpl;
/**
* <p>@description : 该类功能 产品工厂
* </p>
* <p>@package : com.zixieqing.o1simplefactory.o2complex</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class CommodityFactory {
/**
* <p>@description : 该方法功能 获取产品
* </p>
* <p>@methodName : getCommodity</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
* @param type 产品类型
* @return com.zixieqing.o1simplefactory.o2complex.ICommodityService
*/
public ICommodityService getCommodity(Integer type) {
if (1 == type) return new CouponCommodityServiceImpl();
if (2 == type) return new QvodCommodityServiceImpl();
if (3 == type) return new GoodsCommodityServiceImpl();
throw new RuntimeException("不合法的商品类型");
}
}
8、测试
package com.zixieqing;
import com.zixieqing.o1simplefactory.o1simplelogic.IShopping;
import com.zixieqing.o1simplefactory.o1simplelogic.ShoppingFactory;
import com.zixieqing.o1simplefactory.o2complex.CommodityFactory;
import com.zixieqing.o1simplefactory.o2complex.ICommodityService;
import java.util.UUID;
/**
* <p>@description : 该类功能 测试
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class APITest {
public static void main(String[] args) throws Exception{
System.out.println("================华丽的分割线:简单结合业务开发进行测试===================");
CommodityFactory commodityFactory = new CommodityFactory();
// 1、优惠卡类型
ICommodityService commodity_1 = commodityFactory.getCommodity(1);
commodity_1.sendCommodity(System.nanoTime() + "",
System.currentTimeMillis() + "",
UUID.randomUUID() + "",
null);
// 2、快播兑换卡
ICommodityService commodity_2 = commodityFactory.getCommodity(2);
commodity_2.sendCommodity(System.nanoTime() + "",
System.currentTimeMillis() + "",
UUID.randomUUID() + "",
null);
// 3、实物购买
ICommodityService commodity_3 = commodityFactory.getCommodity(3);
HashMap<String, String> extMap = new HashMap<>();
extMap.put("consigneeUserName", "紫邪情");
extMap.put("consigneeUserPhone", "31343214321432");
extMap.put("consigneeUserAddress", "浙江省.杭州市.余杭区.XX街道.YY小区.324134321431");
commodity_3.sendCommodity(System.nanoTime() + "",
System.currentTimeMillis() + "",
UUID.randomUUID() + "",
extMap);
}
}

废话文学

定义:定义一个创建对象的接口,但由子类(具体工厂)决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类
解决的问题:明确地计划不同条件下创建不同实例时就可以考虑是否采用工厂模式,从而提高扩展性,减少以后的改代码量
废话文学:
工厂方法模式的角色
工厂方法模式这玩意儿其实就是在简单工厂的基础上稍微变了一下而已,多了一层罢了(没什么是加一层解决不了的,一层不行,那就再来一层),这里加的这一层就是对业务层再抽象了一下而已
简单工厂是纵向发展(不断添加实现类),而工厂方法模式本质是为了解决简单工厂模式的问题(违背开闭原则),所以优点和简单工厂模式一样,其是横向发展(不断添加工厂类+实现类)
简单工厂模式

工厂方法模式:

这个东西其实在刚刚前面的代码中有一个东西就用到了,即:SLF4J日志门面,前面用了一个LoggerFactory,它里面就用到了工厂方法模式
1、进入getLogger()
// 进入getLogger()
private Logger logger = LoggerFactory.getLogger(QvodService.class);
// 得到的代码
public static Logger getLogger(Class clazz) {
// 进入这里的getLogger()
return getLogger(clazz.getName());
}
// 得到代码
public static Logger getLogger(String name) {
// 再看一下getILoggerFactory()
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}
// getILoggerFactory()的代码
public static ILoggerFactory getILoggerFactory() {
if (INITIALIZATION_STATE == 0) {
INITIALIZATION_STATE = 1;
performInitialization();
}
switch(INITIALIZATION_STATE) {
case 1:
// 重点1、static SubstituteLoggerFactory TEMP_FACTORY = new SubstituteLoggerFactory();
return TEMP_FACTORY;
case 2:
throw new IllegalStateException("org.slf4j.LoggerFactory could not be successfully initialized. See also http://www.slf4j.org/codes.html#unsuccessfulInit");
case 3:
return StaticLoggerBinder.getSingleton().getLoggerFactory();
case 4:
// 重点2、static NOPLoggerFactory NOP_FALLBACK_FACTORY = new NOPLoggerFactory();
return NOP_FALLBACK_FACTORY;
default:
throw new IllegalStateException("Unreachable code");
}
}
TEMP_FACTORY、NOP_FALLBACK_FACTORY都实现了ILoggerFactory2、看一眼ILoggerFactory
// 这个就是根工厂:定义最大规则的那个叼毛
public interface ILoggerFactory {
Logger getLogger(String var1);
}
逆向回来,逻辑就变成如下的样子

废话文学
在开发中怎么使用工厂方法模式(下列逻辑不止适用于此模式,创建型、行为型、结构型均适合,了解每种类型针对的是对什么做架构即可,如:是对类中方法、还是类本身等等做架构来进行抽离,最后时间长了一看需求就知道咋个设计了)
1、思考自己要创建的几个实例( 即:具体产品)有什么共通性
2、将共通性抽取出来变成一个接口或抽象类(即:抽象产品)
3、思考对每一个实例(产品)弄一个工厂类之后(即:具体工厂),那这几个工厂类之间又有什么共通性
4、将工厂类的共通性抽取出来变成一个接口(即:抽象工厂)
5、当然:再考虑以后应该会在什么地方添加功能、是否会扩展的话更好,但这一条需要经验积累
6、然后使用下图方式做架构即可

场景:文件解析,假设有两种:1、xml文件解析;2、json文件解析
逻辑如下

1、抽象产品
package com.zixieqing.o2factorymethod;
/**
* <p>@description : 该类功能 文件解析器
* </p>
* <p>@package : com.zixieqing.o2factorymethod</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IFileParser {
String parse();
}
2、具体产品
package com.zixieqing.o2factorymethod.impl;
import com.zixieqing.o2factorymethod.IFileParser;
/**
* <p>@description : 该类功能 json文件解析器
* </p>
* <p>@package : com.zixieqing.o2factorymethod.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class JsonFileParse implements IFileParser {
@Override
public String parse() {
return "这里就搞json文件解析的逻辑";
}
}
package com.zixieqing.o2factorymethod.impl;
import com.zixieqing.o2factorymethod.IFileParser;
/**
* <p>@description : 该类功能 xml文件解析器
* </p>
* <p>@package : com.zixieqing.o2factorymethod</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class XMLFileParse implements IFileParser {
@Override
public String parse() {
return "这里就搞xml文件的解析逻辑";
}
}
3、抽象工厂
package com.zixieqing.o2factorymethod.factory;
import com.zixieqing.o2factorymethod.IFileParser;
/**
* <p>@description : 该类功能 解析器抽象工厂
* </p>
* <p>@package : com.zixieqing.o2factorymethod</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IParserFactory {
IFileParser parse();
}
4、具体工厂
package com.zixieqing.o2factorymethod.factory.impl;
import com.zixieqing.o2factorymethod.IFileParser;
import com.zixieqing.o2factorymethod.factory.IParserFactory;
import com.zixieqing.o2factorymethod.impl.JsonFileParse;
/**
* <p>@description : 该类功能 json解析工厂
* </p>
* <p>@package : com.zixieqing.o2factorymethod.factory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class JsonParseFactory implements IParserFactory {
@Override
public IFileParser parse() {
return new JsonFileParse();
}
}
package com.zixieqing.o2factorymethod.factory.impl;
import com.zixieqing.o2factorymethod.IFileParser;
import com.zixieqing.o2factorymethod.factory.IParserFactory;
import com.zixieqing.o2factorymethod.impl.XMLFileParse;
/**
* <p>@description : 该类功能 xml解析工厂
* </p>
* <p>@package : com.zixieqing.o2factorymethod.factory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class XMLParseFactory implements IParserFactory {
@Override
public IFileParser parse() {
return new XMLFileParse();
}
}
定义:在工厂方法模式的基础上,对工厂进行变化一下
解决的问题:产品簇的问题(一个中心工厂来创建其他工厂)
对于产品簇百度有一个通俗易懂的解释:指具有相同或相似的功能结构或性能,共享主要的产品特征、组件或子结构,并通过变型配置来满足特定市场的一组产品的聚类
废话文学对产品簇的解释:产品簇是指工厂生产出的产品们之间彼此具备强关联。比如:AK47工厂生产的 AK47步枪、AK47专配的子弹,一旦 AK47装错了子弹是无法正常开枪的(甚至会炸膛)
抽象工厂模式的角色
抽象工厂模式逻辑举例(上面的四角色自行对应)

就用上面说的家具来举例
1、椅子接口(抽象产品)
package com.zixieqing.o3abstractfactory;
/**
* <p>@description : 该类功能 抽象产品:椅子接口
* </p>
* <p>@package : com.zixieqing.o3abstractfactory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IChair {
/**
* <p>@description : 该方法功能 生产椅子
* </p>
* <p>@methodName : createChair</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
*
* @return java.lang.String
*/
String create();
}
package com.zixieqing.o3abstractfactory.impl;
import com.zixieqing.o3abstractfactory.IChair;
/**
* <p>@description : 该类功能 具体产品:木质椅子
* </p>
* <p>@package : com.zixieqing.o3abstractfactory.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class WoodenChair implements IChair {
@Override
public String create() {
return "木质椅子";
}
}
package com.zixieqing.o3abstractfactory.impl;
import com.zixieqing.o3abstractfactory.IChair;
/**
* <p>@description : 该类功能 具体产品:塑料椅子
* </p>
* <p>@package : com.zixieqing.o3abstractfactory.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class PlasticChair implements IChair {
@Override
public String create() {
return "塑料椅子";
}
}
2、桌子接口(抽象产品)
package com.zixieqing.o3abstractfactory;
/**
* <p>@description : 该类功能 抽象产品:桌子接口
* </p>
* <p>@package : com.zixieqing.o3abstractfactory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IDesk {
/**
* <p>@description : 该方法功能 生产桌子
* </p>
* <p>@methodName : create</p>
* <p>@author: ZiXieqing</p>
* <p>@version: V1.0.0</p>
*
* @return java.lang.String
*/
String create();
}
package com.zixieqing.o3abstractfactory.impl;
import com.zixieqing.o3abstractfactory.IDesk;
/**
* <p>@description : 该类功能 具体产品:木质桌子
* </p>
* <p>@package : com.zixieqing.o3abstractfactory.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class WoodenDesk implements IDesk {
@Override
public String create() {
return "木质桌子";
}
}
package com.zixieqing.o3abstractfactory.impl;
import com.zixieqing.o3abstractfactory.IDesk;
/**
* <p>@description : 该类功能 具体产品:塑料桌子
* </p>
* <p>@package : com.zixieqing.o3abstractfactory.impl</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class PlastidDeck implements IDesk {
@Override
public String create() {
return "塑料桌子";
}
}
3、家具抽象工厂
package com.zixieqing.o3abstractfactory;
/**
* <p>@description : 该类功能 抽象工厂:家具工厂
* </p>
* <p>@package : com.zixieqing.o3abstractfactory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IFurnitureFactory {
IChair createChair();
IDesk createDesk();
}
package com.zixieqing.o3abstractfactory.factory;
import com.zixieqing.o3abstractfactory.IChair;
import com.zixieqing.o3abstractfactory.IDesk;
import com.zixieqing.o3abstractfactory.IFurnitureFactory;
import com.zixieqing.o3abstractfactory.impl.WoodenChair;
import com.zixieqing.o3abstractfactory.impl.WoodenDesk;
/**
* <p>@description : 该类功能 具体工厂:专门生产木质家具这一产品簇需要的东西
* </p>
* <p>@package : com.zixieqing.o3abstractfactory.factory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class WoodenIFurnitureFactory implements IFurnitureFactory {
@Override
public IChair createChair() {
return new WoodenChair();
}
@Override
public IDesk createDesk() {
return new WoodenDesk();
}
}
package com.zixieqing.o3abstractfactory.factory;
import com.zixieqing.o3abstractfactory.IChair;
import com.zixieqing.o3abstractfactory.IDesk;
import com.zixieqing.o3abstractfactory.IFurnitureFactory;
import com.zixieqing.o3abstractfactory.impl.PlasticChair;
import com.zixieqing.o3abstractfactory.impl.PlastidDeck;
/**
* <p>@description : 该类功能 具体工厂:专门生产塑料家具这一产品簇需要的东西
* </p>
* <p>@package : com.zixieqing.o3abstractfactory</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class PlasticFurnitureFactory implements IFurnitureFactory {
@Override
public IChair createChair() {
return new PlasticChair();
}
@Override
public IDesk createDesk() {
return new PlastidDeck();
}
}
4、测试
package com.zixieqing;
import com.zixieqing.o3abstractfactory.factory.PlasticFurnitureFactory;
import com.zixieqing.o3abstractfactory.factory.WoodenIFurnitureFactory;
/**
* <p>@description : 该类功能 测试
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class AbstractFactoryTest {
public static void main(String[] args) {
// 木质椅子
String chair = new WoodenIFurnitureFactory().createChair().create();
// 木质桌子
String desk = new PlasticFurnitureFactory().createDesk().create();
System.out.println(chair + "+" +desk);
// 想要塑料家具这个产品簇的东西,就去找塑料家具工厂即可
}
}
废话文学
1、首先两个模式都可以生产产品 / 创建实例
2、其次看前面的定义:
3、情景理解:
4、在场景上(注意看下图,两个很像的,但注意看下图中抽象工厂、抽象产品这两个地方):



定义:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示;另外:建造者模式又叫生成器模式
换言之:将多个简单对象通过一步一步组装,最后变成复杂对象的过程;同时:简单对象之间的组装(相同的物料)通过相似的组装过程可以得到不一样的复杂对象(即:相同 / 相似的物料,不同的繁琐组装,得到不同的对象[此对象是一个复杂对象])
典型例子: 计算机有显示器、鼠标、键盘等等部件,不同用户想要的电脑样子、配置不一样,但都只需要和售卖员讲一下自己要的,最后店铺就会组装好用户想要的电脑给用户
注意:核心点是“相同 或 相似的组成成分”,即:创建对象需要很多步骤,但是步骤的顺序不一定固定,这种场景才是使用建造者模式的最佳场景(开发经典例子:一个类的内部结构很复杂,如有很多属性时,就可以考虑用建造者模式改造一下)
建造者角色
注:以下逻辑不是固定的,可以随意变化

package com.zixieqing.o1simple;
/**
* <p>@description : 该类功能 产品对象:电脑
* </p>
* <p>@package : com.zixieqing.o1simple</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class Computer {
/**
* 电脑主机
*/
private String host;
/**
* 电脑显示器
*/
private String monitor;
/**
* 扩展信息
*/
private String extendMap;
@Override
public String toString() {
return "Computer{" +
"host='" + host + '\'' +
", monitor='" + monitor + '\'' +
", extendMap='" + extendMap + '\'' +
'}';
}
public void setHost(String host) {
this.host = host;
}
public void setMonitor(String monitor) {
this.monitor = monitor;
}
public void setExtendMap(String extendMap) {
this.extendMap = extendMap;
}
}
package com.zixieqing.o1simple.builder;
import com.zixieqing.o1simple.Computer;
/**
* <p>@description : 该类功能 抽象建造者:老板 约束下级
* </p>
* <p>@package : com.zixieqing.o1simple</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IComputerBuilder {
IComputerBuilder buildHost();
IComputerBuilder buildMonitor();
IComputerBuilder buildExtendMap();
Computer getComputer();
}
package com.zixieqing.o1simple.builder;
import com.zixieqing.o1simple.Computer;
/**
* <p>@description : 该类功能 具体建造者:干活的员工
* </p>
* <p>@package : com.zixieqing.o1simple.builder</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class ComputerBuilder implements IComputerBuilder{
/**
* 组合产品对象
*/
private Computer computer = new Computer();
/**
* 产品对象零部件:建造主机
*/
@Override
public ComputerBuilder buildHost() {
computer.setHost("主机配置");
/*
返回this就是成为链式调用的关键,如:
computerBuilder.buildMonitor()
.buildHost()
.buildExtendMap()
.getComputer();
*/
return this;
}
/**
* 产品对象零部件:显示器类型
*/
@Override
public ComputerBuilder buildMonitor() {
computer.setMonitor("显示器类型");
return this;
}
/**
* 产品对象零部件:额外信息
*/
@Override
public ComputerBuilder buildExtendMap() {
computer.setExtendMap("额外信息");
return this;
}
/**
* 返回构建好的复杂对象 / 产品对象
*/
@Override
public Computer getComputer() {
return computer;
}
}
package com.zixieqing.o1simple.builder;
import com.zixieqing.o1simple.Computer;
/**
* <p>@description : 该类功能 指挥者:拿图纸的工程师,负责产品对象的构建顺序
* </p>
* <p>@package : com.zixieqing.o1simple.builder</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class ComputerDirector {
private static IComputerBuilder computerBuilder = new ComputerBuilder();
public static Computer getComputer() {
// 1、先搞显示器
return computerBuilder.buildMonitor()
// 在搞主机配置(这里能够进行链式调用,就是因为具体建造者中建造各部件(属性)时使用了return this的原因)
.buildHost()
// 最后弄其他配置信息
.buildExtendMap()
.getComputer();
}
}
package com.zixieqing;
import com.zixieqing.o1simple.builder.ComputerDirector;
/**
* <p>@description : 该类功能 测试
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class APITest {
public static void main(String[] args) {
System.out.println(ComputerDirector.getComputer());
}
}
Computer{host='主机配置', monitor='显示器类型', extendMap='额外信息'}
有的时候会面临一种情况

package com.zixieqing;
import com.zixieqing.o1simple.Computer;
import com.zixieqing.o1simple.builder.ComputerBuilder;
import com.zixieqing.o1simple.builder.ComputerDirector;
import com.zixieqing.o1simple.builder.IComputerBuilder;
/**
* <p>@description : 该类功能 测试
* </p>
* <p>@package : com.zixieqing</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public class APITest {
public static void main(String[] args) {
IComputerBuilder computerBuilder = new ComputerBuilder();
Computer computer = computerBuilder.buildHost()
.buildExtendMap()
.buildMonitor()
.getComputer();
System.out.println(computer);
}
}
StringBuilder的append()这个API的设计模式,当然:要是使用过MyBatis的xml开发模式,那里面有一个使用SqlSessionFactoryBuilder来获取SqlSessionFactory,这里也用到了这个设计模式,甚至Spring底层的BeanDefinitionBuilder通过getBeanDefinition获取BeanDefinition对象也用到了
StringBuilder builder = new StringBuilder();
builder.append("张三")
.append("李四")
.append("大刀王五")
.append("王麻子");
package com.zixieqing.o1simple.builder;
import com.zixieqing.o1simple.Computer;
/**
* <p>@description : 该类功能 抽象建造者:老板 约束下级
* </p>
* <p>@package : com.zixieqing.o1simple</p>
* <p>@author : ZiXieqing</p>
* <p>@version : V1.0.0</p>
*/
public interface IComputerBuilder {
// 这样甩手掌柜就可以甩得稍微彻底点了
IComputerBuilder buildHost(String host);
IComputerBuilder buildMonitor(String monitor);
IComputerBuilder buildExtendMap(String extendMap);
Computer getComputer();
}
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?