背景
本篇主要是java学习过程中编写的练手代码,都是很基础的东西,但又觉得以后可能会用到,特此记录。
常见设计模式
将常见的几种设计模式进行实现,由于之前是C++er,因此实现主要是基于之前学习C++时看的设计模式代码进行修改的。
参考资料:subingwen.cn/design-patt… 这个博客介绍的设计模式简单易懂且全面,力推,不过是用C++实现的。
由于上述博客介绍的很详细,在此就不在介绍各设计模式了。
单例模式
// 懒汉模式
public class Singleton {
private volatile static Singleton singleton = null;
private Singleton() {}
public void print() {
System.out.println("Singleton");
}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
public static void main(String[] args) {
Singleton sgn = Singleton.getSingleton();
sgn.print();
}
}
// 饿汉模式
public class Singleton {
private Singleton() {}
public void print() {
System.out.println("helloworld");
}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
public static void main(String[] args) {
Singleton sgn = Singleton.getInstance();
sgn.print();
}
}
简单工厂模式
interface Smile {
void transform();
void ability();
}
/*
abstract class Smile {
public abstract void transform();
public abstract void ability();
}
*/
class SheepSmile implements Smile {
public void transform() {
System.out.println("变成人兽 -- 山羊人形态...");
}
public void ability() {
System.out.println("将手臂变成绵羊角的招式 -- 巨羊角");
}
}
class LionSmile implements Smile {
public void transform() {
System.out.println("变成人兽 -- 狮子人形态...");
}
public void ability() {
System.out.println("火遁.豪火球之术");
}
}
class BatSmile implements Smile {
public void transform() {
System.out.println("变成人兽 -- 蝙蝠人形态...");
}
public void ability() {
System.out.println("声纳引箭之万剑归宗...");
}
}
public class SimpleFactory {
enum Type {
SHEEP, LION, BAT
}
public Smile CreateSmile(Type type) {
Smile res = null;
switch (type) {
case SHEEP:
res = new SheepSmile();
break;
case LION:
res = new LionSmile();
break;
case BAT:
res = new BatSmile();
break;
default:
break;
}
return res;
}
public static void main(String[] args) {
SimpleFactory factory = new SimpleFactory();
Smile ob = factory.CreateSmile(Type.BAT);
ob.transform();
ob.ability();
}
}
工厂模式
class SheepSmile implements Smile {
public void transform() {
System.out.println("变成人兽 -- 山羊人形态...");
}
public void ability() {
System.out.println("将手臂变成绵羊角的招式 -- 巨羊角");
}
}
class LionSmile implements Smile {
public void transform() {
System.out.println("变成人兽 -- 狮子人形态...");
}
public void ability() {
System.out.println("火遁.豪火球之术");
}
}
class BatSmile implements Smile {
public void transform() {
System.out.println("变成人兽 -- 蝙蝠人形态...");
}
public void ability() {
System.out.println("声纳引箭之万剑归宗...");
}
}
interface SmileFactory {
public Smile createSmile();
}
class SheepFactory implements SmileFactory {
public Smile createSmile() {
return new SheepSmile();
}
}
class LionFactory implements SmileFactory {
public Smile createSmile() {
return new LionSmile();
}
}
class BatFactory implements SmileFactory {
public Smile createSmile() {
return new BatSmile();
}
}
public class Factory {
public static void main(String[] args) {
SmileFactory factory = new LionFactory();
Smile smile = factory.createSmile();
smile.ability();
}
}
抽象工厂模式
// 船体
abstract class ShipBody {
public abstract String getShipBody();
}
class WoodBody extends ShipBody {
@Override
public String getShipBody() {
return "用木材制作船体!";
}
}
class IronBody extends ShipBody {
@Override
public String getShipBody() {
return "用钢铁制作船体!";
}
}
class MetalBody extends ShipBody {
@Override
public String getShipBody() {
return "用合金制作船体!";
}
}
// 武器
abstract class Weapon {
public abstract String getWeapon();
}
class Gun extends Weapon {
@Override
public String getWeapon() {
return "武器--枪";
}
}
class Laser extends Weapon {
@Override
public String getWeapon() {
return "武器--激光";
}
}
class Cannon extends Weapon {
@Override
public String getWeapon() {
return "武器--机关炮";
}
}
// 动力
abstract class Engine {
public abstract String getEngine();
}
class Human extends Engine {
@Override
public String getEngine() {
return "动力--人";
}
}
class Diesel extends Engine {
@Override
public String getEngine() {
return "动力--内燃机";
}
}
class Nuclear extends Engine {
@Override
public String getEngine() {
return "动力--核能";
}
}
class Ship {
ShipBody body;
Weapon weapon;
Engine engine;
Ship(ShipBody body, Weapon weapon, Engine engine) {
this.body = body;
this.weapon = weapon;
this.engine = engine;
}
public String getProperty() {
return body.getShipBody() + weapon.getWeapon() + engine.getEngine();
}
}
abstract class Factory {
public abstract Ship createShip();
}
class BasicFactory extends Factory {
@Override
public Ship createShip() {
Ship ship = new Ship(new WoodBody(), new Gun(), new Human());
System.out.println("《基础型》战船生产完毕");
return ship;
}
}
class StandardFactory extends Factory {
@Override
public Ship createShip() {
Ship ship = new Ship(new IronBody(), new Cannon(), new Diesel());
System.out.println("《标准型》战船生产完毕");
return ship;
}
}
class UltimateFactory extends Factory {
@Override
public Ship createShip() {
Ship ship = new Ship(new MetalBody(), new Laser(), new Nuclear());
System.out.println("《旗舰型》战船生产完毕");
return ship;
}
}
public class AbstractFactory {
public static void main(String[] args) {
Factory factory = new StandardFactory();
Ship ship = factory.createShip();
System.out.println(ship.getProperty());
}
}
代理模式
abstract class Communication {
public abstract void communicate();
}
class Speaker extends Communication {
@Override
public void communicate() {
System.out.println("开始说话...");
System.out.println("通话时发生类一系列的表情变化...");
}
}
class DenDenMushi extends Communication {
private boolean isAgent = false;
private Speaker speaker = null;
DenDenMushi() {
isAgent = true;
speaker = new Speaker();
}
public boolean isAgent() {
return isAgent;
}
@Override
public void communicate() {
if (isAgent()) {
System.out.println("电话虫开始实时模仿通话者的语言和表情...");
speaker.communicate();
}
}
}
public class AgentPattern {
public static void main(String[] args) {
Communication comm = new Speaker();
comm.communicate();
System.out.println("===================");
comm = new DenDenMushi();
comm.communicate();
}
}
观察者模式
abstract class NewAgency{
protected ArrayList<Observer> list = new ArrayList<>();
public abstract void notify(String msg);
public void attach(Observer ob) {
list.add(ob);
}
public void deatch(Observer ob) {
list.remove(ob);
}
}
class Morgans extends NewAgency {
@Override
public void notify(String msg) {
System.out.println("摩根斯新闻社报纸的订阅者一共有 " + list.size() + " 人");
for (Observer ob : list) {
ob.update(msg);
}
}
}
class Gossip extends NewAgency {
@Override
public void notify(String msg) {
System.out.println("八卦新闻社报纸的订阅者一共有 " + list.size() + " 人");
for (Observer ob : list) {
ob.update(msg);
}
}
}
abstract class Observer {
protected String name;
protected NewAgency news;
Observer(String name, NewAgency news) {
this.name = name;
this.news = news;
this.news.attach(this);
}
public void unsubscribe() {
this.news.deatch(this);
}
public abstract void update(String msg);
}
class Dragon extends Observer {
Dragon(String name, NewAgency news) {
super(name, news);
}
@Override
public void update(String msg) {
System.out.println("路飞的老爸革命军龙收到消息:" + msg);
}
}
class Shanks extends Observer {
Shanks(String name, NewAgency news) {
super(name, news);
}
@Override
public void update(String msg) {
System.out.println("路飞的引路人红发香克斯收到消息:" + msg);
}
}
class Bartolomeo extends Observer {
Bartolomeo(String name, NewAgency news) {
super(name, news);
}
@Override
public void update(String msg) {
System.out.println("路飞的头号粉丝巴托洛米奥收到消息:" + msg);
}
}
public class ObserverPattern {
public static void main(String[] args) {
Morgans ms = new Morgans();
Gossip gossip = new Gossip();
Dragon dragon = new Dragon("蒙奇.D.龙", ms);
Shanks shanks = new Shanks("香克斯", ms);
Bartolomeo barto = new Bartolomeo("8️巴托洛米奥", gossip);
ms.notify("蒙奇D路飞成为新世界的新的四皇之一,赏金30亿贝里!");
ms.deatch(dragon);
ms.notify("蒙奇D路飞成为新世界的新的四皇之一,赏金30亿贝里!");
System.out.println("==================================");
gossip.notify("女帝汉库克想要嫁给路飞,给路飞生猴子!");
}
}
生产者-消费者模式
// 三种方式
// 方式一 wait/notifyAll实现
public class PC_wait_notifyAll {
static class Producer implements Runnable {
private List<Integer> list;
private int maxLength;
public Producer(List<Integer> list, int maxLength) {
this.list = list;
this.maxLength = maxLength;
}
@Override
public void run() {
while (true) {
synchronized(list) {
try{
while (list.size() == maxLength) {
System.out.println("生产者" + Thread.currentThread().getName() + " list以达到最大容量,进行wait");
list.wait();
System.out.println("生产者" + Thread.currentThread().getName() + " 退出wait");
}
Random random = new Random();
int i = random.nextInt();
System.out.println("生产者" + Thread.currentThread().getName() + " 生产数据" + i);
list.add(i);
list.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
static class Consumer implements Runnable {
private List<Integer> list;
public Consumer(List list) {
this.list = list;
}
@Override
public void run() {
while (true) {
synchronized (list) {
try{
while (list.isEmpty()) {
System.out.println("消费者" + Thread.currentThread().getName() + " list为空,进行wait");
list.wait();
System.out.println("消费者" + Thread.currentThread().getName() + " 退出wait");
}
Integer element = list.remove(0);
System.out.println("消费者" + Thread.currentThread().getName() + " 消费数据:" + element);
list.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
ExecutorService service = Executors.newFixedThreadPool(15);
for (int i = 0; i < 5; ++i) {
service.submit(new Producer(linkedList, 8));
}
for (int i = 0; i < 10; ++i) {
service.submit(new Consumer(linkedList));
}
}
}
// 方式二 await/signal
public class PC_await_signalAll {
private static ReentrantLock lock = new ReentrantLock();
private static Condition full = lock.newCondition();
private static Condition empty = lock.newCondition();
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
ExecutorService executorService = Executors.newFixedThreadPool(15);
for (int i = 0; i < 5; ++i) {
executorService.submit(new Producer(linkedList, 8, lock));
}
for (int i = 0; i < 10; ++i) {
executorService.submit(new Consumer(linkedList, lock));
}
}
static class Producer implements Runnable {
private List<Integer> list;
private int maxLength;
private Lock lock;
public Producer(List<Integer> list, int maxLength, Lock lock) {
this.list = list;
this.maxLength = maxLength;
this.lock = lock;
}
@Override
public void run() {
while (true) {
lock.lock();
try{
while (list.size() == maxLength) {
System.out.println("生产者" + Thread.currentThread().getName() + " list以达到最大容量,进行wait");
full.await();
System.out.println("生产者" + Thread.currentThread().getName() + " 退出wait");
}
Random random = new Random();
int i = random.nextInt();
System.out.println("生产者" + Thread.currentThread().getName() + " 生产数据" + i);
list.add(i);
empty.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
static class Consumer implements Runnable {
private List<Integer> list;
private Lock lock;
public Consumer(List list, Lock lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
while (true) {
lock.lock();
try{
while (list.isEmpty()) {
System.out.println("消费者" + Thread.currentThread().getName() + " list为空,进行wait");
empty.await();
System.out.println("消费者" + Thread.currentThread().getName() + " 退出wait");
}
Integer element = list.remove(0);
System.out.println("消费者" + Thread.currentThread().getName() + " 消费数据:" + element);
full.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}
// 方式三 BlockingQueue实现
public class PC_BlockingQueue {
private static LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(15);
for (int i = 0; i < 5; ++i) {
service.submit(new Productor(queue));
}
for (int i = 0; i < 10; ++i) {
service.submit(new Consumer(queue));
}
}
static class Productor implements Runnable {
private BlockingQueue queue;
public Productor(BlockingQueue queue) {
this.queue = queue;
}
@Override
public void run() {
try {
while (true) {
Random random = new Random();
int i = random.nextInt();
System.out.println("生产者" + Thread.currentThread().getName() + "生产数据" + i);
queue.put(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class Consumer implements Runnable {
private BlockingQueue queue;
public Consumer(BlockingQueue queue) {
this.queue = queue;
}
@Override
public void run() {
try {
while (true) {
Integer element = (Integer) queue.take();
System.out.println("消费者" + Thread.currentThread().getName() + "正在消费数据" + element);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
发布/订阅(事件总线)框架
简述
基于事件总线的发布/订阅框架
基本版
-
支持发布事件(post)、订阅事件(subscribe)、 解除订阅(unsubscribe)
- 一个事件可以有 多个订阅者,发送事件可以在任意线程发生
- 发布订阅:当发送A类型事件时,所有已订阅A类型事件的 订阅者会接收到回调
- 解除订阅: 某个订阅者解除A类型事件后,再有A类型的事件产生时,不再接收到回调
-
考虑线程安全问题
进阶版
- 支持多线程事件消费能力,订阅事件时,支持消费线程的方式,如在事件发送方线程消费、在异步线程池消费
代码
github:github.com/noResign/Ev…
参考资料
注意点
- 要放入map的对象,得重写hashCode和equals方法
- 测试的时候可以等所有订阅者注册完了在进行发布,这里使用的是CountDownLatch进行协调。如果不这样可能造成某个事件无人订阅
- 事件-订阅者的映射使用了CopyOnWriteArrayList存订阅者们,具有线程安全。但由于在写操作时会产生额外开销