当前位置:网站首页>Sharing ideas for a quick switch to an underlying implementation
Sharing ideas for a quick switch to an underlying implementation
2022-06-26 14:36:00 【Liziti】
High quality resource sharing
| Learning route guidance ( Click unlock ) | Knowledge orientation | Crowd positioning |
|---|---|---|
| 🧡 Python Actual wechat ordering applet 🧡 | Progressive class | This course is python flask+ Perfect combination of wechat applet , From the deployment of Tencent to the launch of the project , Create a full stack ordering system . |
| Python Quantitative trading practice | beginner | Take you hand in hand to create an easy to expand 、 More secure 、 More efficient quantitative trading system |
| Catalog |
- 1. Fast access to new implementations 1: abstract class
- 2. Solve the problems caused by simple abstraction
- 3. A more perfect scheme : Different implementations based on interfaces
The real scene is often like this , We respond to a need , There will soon be a solution , Then, a good implementation is made according to the requirements . Because the function is realized , The business is very happy, The boss is happy ,all the world is beatiful.
But with the development of the company , Someone has implemented an underlying set of standard components , As required, you have to access his , His function is similar to yours , But you have to switch to that . Regardless of the quality of its implementation , But he certainly has some advantages , But as a standard kit , It can't be completely consistent with your needs . therefore , This must involve the problem of transformation .
In this case , We are not willing to take it , After all, the code is running well , Who wants to move ? And how other people achieve , Not tested yet , Rash access , It may bring a larger pot .( from 0 To 1 Nobody cares about accuracy , But from 1 TripAdvisor 1.1 Someone will pay attention to accuracy , In other words, this is called compatibility )
however , Often under pressure , We have to answer again .
At this time, we have two ways , One is to directly change the code to someone else . This treatment is simple and rough , And there are no worries . however , And then , Is a large-scale regression test , And some points that may not be tested , Means code rollback . For some places where online operation and maintenance is more convenient , Maybe we can do this . But this is not the recommended practice in this article , No more discussion .
A more prudent approach , It should be in the case of maintaining the existing implementation , Make the newly realized access , At least you can compare . Advance and attack , Retreat and defend .
Return to the top ### 1. Fast access to new implementations 1: abstract class
Since we dare not directly replace the existing implementation , Then you have to keep two implementations , So you can use abstract classes , While maintaining the original implementation , Cut into new implementations . It's an intuitive idea , The specific implementation is as follows :
1. Abstract a public class
public abstract class AbstractRedisOperate {
private AbstractRedisOperate impl;
public AbstractRedisOperate() {
String strategy = "a"; // from config
if("a".equals(strategy)) {
impl = new RedisOperateA1Imp();
}
else {
impl = new RedisOperateB2Imp();
}
}
// Example operation interface
public void set(String key, String value);
}
- Implement two concrete classes
// Realization 1, Completely dependent on abstract class implementation ( Old functions )
public class RedisOperateOldImp extends AbstractRedisOperate {
}
// Realization 2, Implementation of new access
public class RedisOperateB2Imp extends AbstractRedisOperate {
@Override
public void set(String key, String value) {
System.out.println("this is b's implement...");
}
}
- Keep the original implementation class entry , Turn its implementation into a facade class or an adapter class
// Loading entry
@Service
public class RedisOperateFacade extends AbstractRedisOperate {
public RedisOperateFacade() {
// case1. Leave it directly to the parent class
super();
}
@Override
public void set(String key, String value) {
// fake impl
}
}
What are the benefits of the above implementation ? First , Existing implementations are pulled away , And it was preserved without any changes . The new implementation class implements a new . Through a common changeover switch , Perform switching processing . thus , It can ensure the access to the new implementation , It also retains the old implementation , In the event of an unknown failure , Can be implemented by failback .
What is the problem with the above implementation ?
When we run the code above , I found the wrong report , Why? ? Because there is a dead circle . Although we only loaded one Facade The implementation of the , But in calling super when ,super The concrete implementation will be loaded in turn , The concrete implementation will load the abstract classes super, And so on and so on , Until the stack overflows . Also known as the emergence of a dead cycle .
Return to the top ### 2. Solve the problems caused by simple abstraction
In the previous section, we already knew why the loading failed , In fact, it is a circular dependency problem . How to solve it ?
It's simply moving the code , Don't put judgment in the default constructor , Handled by a concrete appearance class , The loading policy is determined by the appearance class , Instead of concrete implementation classes or abstract classes .
The specific operation is as follows :
// 1. Appearance class controls loading
@Service
public class RedisOperateFacade extends AbstractRedisOperate {
public RedisOperateFacade() {
// case1. Leave it directly to the parent class
// super();
// case2. Decide which implementation to load
String strategy = "a"; // from config center
if("a".equals(strategy)) {
setImpl(new RedisOperateOldImp());
}
else {
setImpl(new RedisOperateB2Imp());
}
}
}
// 2. Each implementation keeps itself still
public class RedisOperateOldImp extends AbstractRedisOperate {
// old impl...
}
public class RedisOperateB2Imp extends AbstractRedisOperate {
// new impl...
@Override
public void set(String key, String value) {
System.out.println("this is b's implement...");
}
}
// 3. Abstract classes are no longer subject to load policy processing
public abstract class AbstractRedisOperate {
// Hold concrete realization
private AbstractRedisOperate impl;
public AbstractRedisOperate() {
}
protected void setImpl(AbstractRedisOperate impl) {
this.impl = impl;
}
// Example operation interface , old impl...
public abstract void set(String key, String value);
}
Made minor changes , Transfer the loading policy from the abstract class to the appearance class , The correct loading effect can be achieved . actually , For the sake of simplicity , We can even make the original implementation complete copy Into abstract classes , And a new original implementation class , You don't have to do anything , Just add an empty inheritance abstract class . And the new implementation , Then it is enough to completely cover the existing concrete implementation . So as to achieve a minimum change , And smoothly access a newly implemented effect .
But if it depends on the concrete implementation of the abstract class , There's a problem , That is, if our subclasses are not well implemented , For example, when some implementations are omitted , The code itself does not give an error message . This brings us potential risks , Because that would turn into , Part is the old implementation , The other part is the new implementation . There may be two problems : One is that one of the two implementations reports an error and the other is normal ; Second, rollback cannot be switched normally , The two implementations are coupled together .
Return to the top ### 3. A more perfect scheme : Different implementations based on interfaces
What shall I do? ? We can abstract another layer of interfaces , Each implementation deals with the interface , Only the appearance class inherits the abstract class , And the abstract class also implements the interface definition . In this case , This ensures the integrity of each implementation , And the uniformity of appearance classes . here , I take advantage of the mandatory nature of grammar , That is, the semantics of the interface must be implemented , Ensure the accuracy of the code .( Yes, of course , All the real scenes , Interfaces must have corresponding implementations , Because only interfaces are visible from the outside , If not, it must be illegal )
The specific implementation is as follows :
//1. Unified interface definition
public interface UnifiedRedisOperate {
void set(String key, String value, int ttl);
// more interface definitions...
}
// 2. Each sub implementation class
public class RedisOperateOldImp implements UnifiedRedisOperate {
@Override
public void set(String key, String value) {
System.out.println("this is a's implement...");
}
}
public class RedisOperateB2Imp implements UnifiedRedisOperate {
@Override
public void set(String key, String value) {
System.out.println("this is b's implement...");
}
}
// 3. Implementation of appearance class
@Service
public class RedisOperateFacade extends AbstractRedisOperate {
public RedisOperateFacade() {
// case1. Leave it directly to the parent class
// super();
// case2. Appearance class controls loading
String strategy = "a"; // from config center
if("a".equals(strategy)) {
setImpl(new RedisOperateOldImp());
}
else {
setImpl(new RedisOperateB2Imp());
}
}
}
public abstract class AbstractRedisOperate implements UnifiedRedisOperate {
private UnifiedRedisOperate impl;
protected void setImpl(UnifiedRedisOperate impl) {
this.impl = impl;
}
// Interface delegation
public void set(String key, String value) {
impl.set(key, value);
}
// more delegates...
}
It seems that an additional interface class has been added , But actually the whole code is much clearer and easier to read . actually , A good design , Initially, it should also be based on interfaces ( Interface oriented programming ), Here we re abstract an interface class , In fact, it is to make up for the shortcomings of the previous design , It is also a kind of refactoring . All implementations are based on interfaces , None of them can be less , Thus reducing the probability of error .
such , We can safely switch production .
The article was originally published on wechat official account : A quick switch to a low-level implementation of ideas to share
边栏推荐
- Win10 home vs pro vs enterprise vs enterprise LTSC
- 数学建模经验分享:国赛美赛对比/选题参考/常用技巧
- Chinese output of PostGIS console is garbled
- ArcGIS cannot be opened and displays' because afcore cannot be found ' DLL, solution to 'unable to execute code'
- Combat readiness mathematical modeling 32 correlation analysis 2
- Codeforces Global Round 21A~D
- Online bull Blogger
- Heap optimization dijkstra/hash table storage node number
- Sword finger offer 10 Ⅰ 10Ⅱ. 63 dynamic planning (simple)
- 2021-10-29 atcoder ABC157——B - Bingo
猜你喜欢

VMware partial settings

Sword finger offer 09.30 Stack

Sword finger offer 18.22.25.52 Double pointer (simple)

Jianzhi offer 43.47.46.48 dynamic planning (medium)

Eigen(3):error: ‘Eigen’ has not been declared

Experience sharing of mathematical modeling: comparison between China and USA / reference for topic selection / common skills

Sword finger offer 06.24.35 Linked list

从Celsius到三箭:加密百亿巨头们的多米诺,史诗级流动性的枯竭

在云服务器中云磁盘如何挂载

Setup instance of layout manager login interface
随机推荐
Oracle ASMM and AMM
Sectigo的IP证书申请流程
9 articles, 6 interdits! Le Ministère de l'éducation et le Ministère de la gestion des urgences publient et publient conjointement neuf règlements sur la gestion de la sécurité incendie dans les établ
启动Redis报错:Could not create Server TCP listening socket *:6379: bind: Address already in use–解决办法
Matplotlib common operations
备战数学建模31-数据插值与曲线拟合3
A标签去掉下划线
Flex & Bison 开始
Gartner 2022年顶级战略技术趋势报告
BM3D in popular language
One article of the quantification framework backtrader read observer
C language | the difference between heap and stack
备战数学建模30-回归分析2
量化框架backtrader之一文读懂observer观测器
idea快捷键
Leaflet loading ArcGIS for server map layers
vmware部分设置
MySQL主从复制与读写分离
NAACL2022:(代码实践)好的视觉引导促进更好的特征提取,多模态命名实体识别(附源代码下载)...
[hnoi2010] flying sheep