Interface Segregation defines like this
Clients should not be forced to implement any methods they don't use
In other word, it's like client(child) says
😩😩 For what I need to implement this one??? I don't need it
We have to prevent this client's(child's) complaint asap !!
👎 Bad code
set Animal Interface
then create Dog class and Fish class
interface IAnimal {
fly: () => void
run: () => void
swim: () => void
}
class Dog implements IAnimal {
// 😩😩😩 For what I need to implement it....
fly() {
null
}
run() {
console.log('running!!!!')
}
swim() {
console.log('swim!!! not so fast though')
}
}
class Fish implements IAnimal {
fly() {
console.log('fly... a little?')
}
// 😩😩😩 For what I need to implement it....
run() {
null
}
swim() {
console.log('swim!! soooooooo fast!!!!!!!!!!')
}
}
As you can see in this code, classes complains For what I need to implement it...
because dog doesn't fly, fish doesn't run !!
👍 Good code
// ⭐ divide interface !
interface IAnimalFly {
fly: () => void
}
interface IAnimalRun {
run: () => void
}
interface IAnimalSwim {
swim: () => void
}
class Dog implements IAnimalRun, IAnimalSwim{
run() {
console.log('dos runs !!')
}
swim() {
console.log('dos swims, not so fast though')
}
// ⭐ Dog doesn't need to implement fly()
}
class Fish implements IAnimalFly, IAnimalSwim {
fly() {
console.log('fish fies... a little?')
}
swim() {
console.log('fish swims so fast !!!!!')
}
// Fish doesn't need to implement run()
}
Thanks for dividing interface, Dog and Fish finally don't complain at all ↓
For what I need to implement this one??? I don't need it
Btw in article Liskof substitute is also dividing interface was important key.
Architecture of interface would be important in SOLID principle, I think
💎 For frontend engineer
I found good sample about interface segregation for frontend engineer, so Im gonna show it as well
👎 Bad code
There is Diary app, at first set type Diary
, then make updateDiaryTitle
function
export type Diary = {
id: string;
title: string;
content: string;
createdAt: Date;
updatedAt: Date;
};
const updateDiaryTitle = async (
// ⭐ here get Diary object
diary: Diary,
updateTitle: (props: {id: string, title: string}) => Promise<void>
): Promise<void> => {
// fetch data from server
await updateTitle({ id: task.id, title: task.title });
};
There is a problem now, if someone change Diary type
like this
type Diary = {
id: string;
diaryInfo: {
// ⭐ title is inside diaryInfo now !!
title: string;
details: string;
},
createdAt: Date;
updatedAt: Date;
};
get a error because of it
const updateDiaryTitle = async (
diary: Diary,
updateTitle: (props: {id: string, title: string}) => Promise<void>
): Promise<void> => {
await updateTitle({ id: task.id, title: task.title });
// => 🔥🔥🔥 Property 'title' does not exist on type 'Diary'.
};
We need to modify updateDiaryTitle
, but it shouldn't depend on Diary
type. So good code would be like this
👍 Good code
const updateDiaryTitle = async (
// ⭐⭐⭐ get "id" and "title" directly
diary: {id: string, title: string},
updateTitle: (props: {id: string, title: string}) => Promise<void>
): Promise<void> => {
await updateTitle({ id: diary.id, title: diary.title });
};
get id
and diary
directly, then you clearly know which property should you use in updateDiaryTitle
function
then when you implement or modify updateDiaryTitle
, you don't need to care about Diary
type at all.
Absolutely you have seen and will see all the time when you pass props to child in React.js or Vue.js 😀 I hope you are going to use this principle effectively someday 👍
ref
https://kanoe.dev/blog/interface-segregation-principle/
https://www.youtube.com/watch?v=JVWZR23B_iE
japanese blog
Top comments (0)