PATTERNS THAT BOOST OUR FRAMEWORKS





Why?
-
Everything is changing very fast!



2009...
-
JQuery, Tapestry, Flash, Flex, Backbone, ie...

2013...
-
AngularJS

2016...
-
Angular, Android

Today...
-
React, Stencil, Flutter, ie... :(

A solution?

A solution?
-
Following the SOLID principles :
-
Building software designs...
-
More understandable
-
Easier to maintain
-
Easier to extend
-
Contents
-
A list of commonly used patterns ;)
-
Starting by a well known structural pattern...
1. MVC
1. MVC
-
A long, long time ago...

1. MVC

1. MVC
-
Angular :
-
View
-
Controller
-
Model
-
HTML Template
-
Component
-
Service
-
React :
-
View
-
Controller
-
Model
-
View
1. MVC
<div>
<app-user-search (changed)="onCriteriaChanged($event)">
</app-user-search>
<app-users-list [users]="users$ | async"
(select)="onSelectUser($event)">
</app-users-list>
</div>
-
"View"
1. MVC
@Component({
templateUrl: './main-page.component.html',
styleUrls: ['./main-page.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MainPageComponent implements OnInit {
users$: Observable<User[]>;
constructor(private userService: UserService) {}
ngOnInit() {
this.users$ = this.userService.fetchUsers();
}
}-
"Controller"
1. MVC
@Injectable()
export class UserService {
constructor(@Inject(USER_API_URL) private urlUsers: string,
private http: HttpClient) {}
fetchUsers(criteria: UserCriteria): Observable<User[]> {
return this.http.get<User[]>(this.urlUsers);
}
}-
"Model"
1. MVC
-
Other structuring patterns :
-
MVP (Model - View - Presenter)

1. MVC
-
Other structuring patterns :
-
MVVM (Model - View - ViewModel)

1. MVC
-
MVVM Android :
class ViewModelActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Obtain the ViewModel component.
UserModel userModel = ViewModelProviders.of(getActivity())
.get(UserModel.class)
// Inflate view and obtain an instance of the binding class.
val binding: UserBinding =
DataBindingUtil.setContentView(this, R.layout.user)
// Assign the component to a property in the binding class.
binding.viewmodel = userModel
}
}1. MVC
-
MVVM Android :
<CheckBox
android:id="@+id/rememberMeCheckBox"
android:checked="@{viewmodel.rememberMe}"
android:onCheckedChanged="@{() -> viewmodel.rememberMeChanged()}" />2. REACTIVE PrograMMING
2. Reactive Programming
-
Asynchronous data streams

2. Reactive Programming
-
Everything is a stream :

2. Reactive Programming
-
Declarative approach using :
-
Pure functions
-
Iterator pattern
-
const products$: Observable<Product[]> =
fromEvent(this.input.nativeElement, 'keyup')
.pipe(
map(event => event.target.value),
filter((search: String) => search.length > 2),
debounceTime(250),
distinctUntilChanged(),
switchMap(search => this.fetchProducts(search))
);
2. Reactive Programming
-
ReactiveX implementations :
-
RxJS
-
RxJava
-
RxKotlin
-
RxDart
-
RxPython
-
...
-

2. Reactive Programming
-
Common uses :
-
Angular HttpClient, ReactiveForms...
-
Android LiveData
-
Flutter FutureBuilder/StreamBuilder
- ...
-
2. Reactive Programming
-
Heavily depends on...
Observer pattern
3. OBSERVER
3. Observer
-
Event handling :
-
Observers
-
Subjects
3. Observer
-
Event handling :

3. Observer
-
Subject :
-
Observer :
-
registerObserver(observer)
-
unregisterObserver(observer)
-
notifyObservers()
-
notify()
3. Observer
-
Main goal :
Separation of concerns
4. SINGLETON
4. Singletons
-
Single instance
-
Coordinate actions across the system
-
Perfect to store data
-
Lazy construction
4. Singletons
-
Angular Services
-
Business specific
-
Transverse
-
@Injectable()
export class UserService {
constructor(@Inject(USER_API_URL) private urlUsers: string,
private http: HttpClient) {}
fetchUsers(): Observable<User[]> {
return this.http.get<User[]>(this.urlUsers);
}
}4. Singletons
-
Angular Services
-
Easy to use...
-
Thanks to Dependency Injection
-
@Component({
templateUrl: './detail-page.component.html',
styleUrls: ['./detail-page.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DetailPageComponent implements OnInit {
users$: Observable<User[]>;
constructor(private userService: UserService) {}
ngOnInit() {
this.users$ = this.userService.fetchUsers();
}
4. Singletons
-
Angular Services
-
Best place to store business data
-
@Injectable()
export class UserService {
private _users$: Observable<User[]>;
get users$(): Observable<User[]> {
return this._users$;
}
constructor(@Inject(USER_API_URL) private urlUsers: string,
private http: HttpClient) {
this._users$ = this.http.get<User[]>(this.urlUsers).pipe(
shareReplay()
);
}
}4. Singletons
-
Redux Store

4. Singletons
⚠️ Warning ⚠️
-
Testability -
Dependency hiding
-
Concurrency
5. FACTORY
5. FACTORY
-
Creational pattern
-
One interface and several implementations
-
Using the Right implementation for a given case

5. FACTORY
-
Generally used with a DI mechanism :
-
Angular services
-
Android libraries (Dagger 2, Koin)
-
Flutter libraries (Inject)
-
5. FACTORY
-
Angular Injection Tokens :
// user.service.ts
export const USER_SERVICE =
new InjectionToken<UserService>('USER_SERVICE');
export interface UserService {
fectchAll(): Observable<User[]>;
fectchOne(): Observable<User>;
}5. FACTORY
-
Angular module :
// app.module.ts
@NgModule({
declarations: [AppComponent],
imports: [
...
],
providers: [
{ provide: USER_SERVICE, useClass: UserServiceHttpImpl },
...
],
bootstrap: [AppComponent]
})
export class AppModule {}5. FACTORY
-
Angular Environments
// app.module.ts
@NgModule({
...
providers: [
{ provide: USER_SERVICE, useClass: environment.userServiceImpl },
...
]
})
export class AppModule {}// environment.ts
{
userServiceImpl: UserServiceHttpImpl
}6. STRATEGY
6. STRATEGY
-
Encapsulates a family of algorithms
-
Makes them interchangeable.

6. STRATEGY
-
In a component architecture :
-
Dumb - Smart components
- Presentational - Container components
-
// detail-page.component.ts
<div class="user-detail-content" *ngIf="user$ | async as user">
<h1>{{ user.firstName }}</h1>
<app-user-form [user]="user" (validate)="onValidate($event)">
</app-user-form>
</div>
7. DECLARATIVE UI
7. Declarative UI
-
The new standard in front development?
-
Declarative API to define UI components
export default class App extends Component {
...
render() {
return (
<div>
<Header />
<List items={this.state.items} />
<Footer />
</div>
);
}
}7. Declarative UI
-
More than just "UI" components :
@override
Widget build(BuildContext context) => FutureBuilder<Restaurant>(
future: restaurantService
.fetchRestaurantDetail(context: context, restaurant: restaurant)
.then((restaurant) => restaurantService.fetchRestaurantRatings(
restaurant: restaurant,
limit: 4
)),
builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
? RestaurantWidget(restaurant: snapshot.data)
: AppProgressIndicator();
});7. Declarative UI
-
At last on Android :
-
Android Jetpack Compose
-
class ComposeActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { CraneWrapper { MyApp() } }
}
@Composable
fun MyApp() {
MaterialTheme {
Text(
text = "Hello world!",
style = +themeTextStyle { h3 }
)
}
}
}Question :
I have developed a components library and want to implement a "disabled" and "tabIndex" state on all of them... ?
8. MIXIN
8. MIXIN
-
Solves a common Class limitation :
-
Single Super Class
-
Share a common behavior between different classes
-
8. MIXIN
-
Mixins can be done in Typescript
-
But it can be a bit tricky
-
Used in some component libraries (Angular Material) to define common behavior such as "color", "disabled"...
8. MIXIN
-
Well implemented in Dart 2.X :
mixin Coder {
void code() {
print("Trying to use design patterns...");
}
}
class Laurent extends Person with Coder {}
void main() {
const laurent = Laurent();
laurent.code();
}8. MIXIN
-
With interface default implementations in Kotlin :
interface Developer {
fun code() {
...
}
}
class UserCodeEnSeine : User, Developper {
...
}8. MIXIN
-
React hooks are Mixins done right :
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>Vous avez cliqué {count} fois</p>
<button onClick={() => setCount(count + 1)}>
Cliquez ici
</button>
</div>
);
}conclusion
To conclude...
-
Patterns are the first thing to learn.
-
Frameworks use them to solve common software development problems.
-
Their implementation differs, but the logic remains the same.
THANKS! 🙏
web-patterns
By Laurent WROBLEWSKI
web-patterns
- 368