框架开发
讲师:李智慧
对扩展是开发,对现有修改是关闭。
使用多态,使用抽象。策略模式,适配器模式,观察者模式。
高层不依赖低层,低层也不依赖高层。高层定义抽象接口,低层实现高层定义的接口。
比如Tomcat,Spring,JUnit,我们不需要调用框架的代码。我们基于框架提供的接口来编程。 架构师要有开发框架的能力和思维,这才能区别于普通的工程师。
正常的调用顺序
依赖倒置以后
所有的父类,都可以替换为子类。 子类比父类更严格,子类方法约束开放性要比父类大。比如父类是protected修饰,子类只能是protected或者public。
不是为继承而设计的类,那么就不要继承该类。
一个类只有一个引起其变化的原因。
如果一个类会有多个原因引起变化,则要分为多个类。
隐藏用户不需要的接口,以免被误操作。
方法调用都是同步的,很快就会把线程池里面的线程给消费完了,导致排队阻塞。
异步处理,通过消息来通信。
Flower 反应式重构前后性能对比
Sender 到 Actor 的通信是异步的,通过消息 Message 进行通信。
public class Hello extends UntypedActor {
@Override
public void onReceive(Object message) {
System.out.println("Hello, world!");
}
}
调用
ActorRef hello = ...
hello.tell("Hi!");
public class ServiceA implements Service<String, String> {
public String process(String message, ServiceContext context) {
return ((String) message).trim();
}
return "";
}
ServiceFlow.getOrCreate(flowName, servcieFactory).buildFlow(ServiceA.class, ServiceB.class).buildFlow(ServiceB.class, ServiceC.class);
flowerFactory.getServiceFacade().asyncCallService(flowName, "Hello World!");
// -> Service1 -> Service2 -> Service5 -> Service4
// ^ | ^ |
// | -> Service3 -| |
// |______________________________________________|
Service1 -> Service2
Service1 -> Service3
Service2 -> Service5
Service3 -> Service5
Service5 -> Service4
Service4 -> Service1
@RestController
@RequestMapping("/order/")
@Flower(value = "createOrderFlow", flowNumber = 32)
public class CreateOrderController extends FlowerController {
@RequestMapping(value = "createOrder")
public void createOrder(OrderExt orderDTO, HttpServletRequest req) throws IOException {
doProcess(orderDTO, req);
}
}
protected void doProcess(Object param, HttpServletRequest req) throws IOExeption {
AsyncContext context = null;
if (req != null) {
context = req.startAsync();
}
flowRouter.asyncCallService(param, context);
}
@FlowerService
public class UserService implements Service<User, CompletableFuture<Serializable>> {
@Autowired
private UserDao userDao;
@override
public CompletableFuture<Serializable> process(User message, ServiceContext context) throws Throwable {
System.out.println("handle user message: " + message);
return userDao.insert(message);
}
}
publci class ServiceActor extends UntypedActor {
Service service;
Set<ActorRef> nextServiceActors;
public ServiceActor(String serviceName) throws Exception {
this.service = ServiceFactory.getService(serviceName);
nextServiceActors = new HashSet<ActorRef>();
Set<String> nextServiceNames = ServiceFlow.getNextFlow(serviceName);
if (nextServiceNames != null && !nextServiceNames.isEmpty()) {
for (String str : nextServiceNames) {
nextServiceActors.add(ServiceActorFactory.buildServiceActor(str));
}
}
}
@Override
public void onReceive(Object arg0) throws Throwable {
Object 0 = service.process(arg0);
if (nextServiceActors != null && !nextServiceActors.isEmpty()) {
for (ActorRef actor : nextServiceActors) {
actor.tell(o, getSelf());
}
}
}
}
package com.ly.train.flower.common.actor;
public class ServiceFacade {
public static void callService(String serviceName, Object o) throws Exception {
ServiceActorFactory.buildServiceActor(serviceName).tell(o, null);
}
}
public class ServiceActorFactory {
final static ActorSystem system = ActorSystem.create("LocalFlower");
private static FiniteDuration duration = Duration.create(3, SECONDS);
public static Map<String, ActorRef> map = new HashMap<String, ActorRef>();
public static ActorRef buildServiceActor(String serviceName) throws Exception {
ActorRef actor = map.get(serviceName);
if (actor != null) {
return actor;
}
actor = system.actorOf(Props,create(ServiceActor.class, serviceName));
return actor;
}
}
Flower 与 WebFlux、RxJava 的比较优势
更好的性能与更低的成本
更高的可用性
开源地址:
https://github.com/zhihuili/flower
从功能分
从方式分
public class SorterFactory {
public static <T> Sorter<T> getSorter() {
return new BubbleSorter<T>();
}
}
public class Client {
public static void main() {
Integer[] array = { 5, 4, 9, 7, 6, 3, 8, 1, 0, 2};
Sorter<Integer> sorter = SorterFactory.getSorter();
Sortable<Integer> sortable = SortableFactory.getSortable(array);
Comparator<Integer> comparator = ComparatorFactory.getComparator();
sorter.sort(sortable, comparator);
......
}
}
优点:
缺点:
class SorterFactory_2 {
@SuppressWarnings("unchecked")
public static <T> Sorter<T> getSorter (String implClass) {
try {
Class impl = Class.forName(implClass);
return (Sorter<T>) impl.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException("Illegal class name:" + implClass, e);
}
}
}
Sorter<Integer> sorter = SorterFactory_2.getSorter("demo.sort.impl.BubbleSorter");
解决了 Factory 的 OCP 问题吗?
其它问题
class SorterFactory_3 {
private final static Properties IMPLS = loadImpls();
private static Properties loadImpls() {
Properties defaultImpls = new Properties();
Properties impls = new Properties(defaultImpls);
defaultImpls.setProperty("sorter", "demo.sort.impl.BubbleSorter");
try {
impls.load(SorterFactory_3.class.getResourceAsStream("sort.properties"));
} catch ( IOException e) {
throw new RuntimeException(e);
}
return impls;
}
@SuppressWarning("unchecked")
public static <T> Sorter<T> getSorter() {
String implClassName = IMPLS.getProperty("sorter");
try {
Class implClass = Class.forName(implClassName);
return (Sorter<T>) implClass.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException("Illegal class name: " + implClassName, e);
}
}
}
创建 sort.proproties
文件
sorter=demo.sort.impl.BubbleSorter
优点
缺点
简单工厂改进做法其实相当重要
Singleton 模式保证产生单一实例,就是说一个类只产生一个实例。试用 Singleton 有两个原因
前者是性能需求,后者是功能需求。
public class HungrySingleton {
private static HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}
注意:一定要有私有的构造函数,保证实例只能通过getInstance()
方法获得。
尽量使用饿汉式构造单实例。单例中的成员变量是多线程重用的,可能会产生意想不到的结果,因此尽量将单例设计为无状态对象(只提供服务,不保存状态)。
饿汉式 Singleton 的问题是,应用一启动就加载对象进内存,就算从来未被用过。
publci class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
注意: getInstance()
的修饰符 synchronized
一定要加上,否则可能会产生多重实例。
懒汉式Singleton解决了饿汉式Singleton,当调用的时候才去加载对象到内存。但是引发了另外一个性能问题,每次访问对象都要加锁。
publci class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (instance == null) {
instance = LazySingleton.buildInstance();
}
return instance;
}
private static synchronized LazySingleton buildInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
只有当对象为null
的时候,才去加锁创建对象。
适配器的作用:
系统需要使用现有的类,而这个类的接口与我们所需要的不同。
由于原 Sortable
接口和 ArrayList
不兼容,只好定义一个 NewSortable
public class Sortable<T> extends ArrayList<T> implements NewSortable<T> {
public T getElement(int i) {
return get(i);
}
public void setElement(int i, T o) {
set(i, o);
}
}
public interface NewSortalbe<T> {
int size();
T getElement(int i);
void setElement(int i, T o);
}
public class ListSortable<T> implements Sortable<T> {
private final List<T> list;
public ListSortable(List<T> list) {
this.list = list;
}
public int size() {
return list.size();
}
public T get(int i) {
return list.get(i);
}
public void set(int i, T o) {
list.set(i, o);
}
}
JDBC Driver
JDBC-ODBC Bridge
注意:以上信息如有侵权,请联系作者删除,谢谢。