36 posts
Software Development Methodology
Object-oriented methodology
Object-Oriented Design Principles (=SOILD)
Five design principles: SRP, OCP, LSP, ISP, DIP SRP(Single Responsibility Principle), Single Responsibility Principle The principle is that a class should have only one responsibility. As you can see in the code below, it is advisable to classify the user-related logic and the email sending logic separately. Try to separate your code so that there is only one responsibility.
class User {
fun register() { }
}
class EmailSender {
fun sendEmail() { }
}
OCP(Open/Closed principle), open-closed principle The principle is that software elements should be open to extension but closed to change.
Dog
class and
Cat
are both
Animal
returning return type
makeSound()
method is used. here
Animal
The class adheres to OCP principles, and can be used as a return type class without change even when creating other animal classes.
// 동물 클래스
open class Animal(val name: String) {
open fun makeSound() {
println("동물이 소리를 내지 않습니다.")
}
}
// 개 클래스
class Dog(name: String) : Animal(name) {
override fun makeSound() {
println("멍멍!")
}
}
// 고양이 클래스
class Cat(name: String) : Animal(name) {
override fun makeSound() {
println("야옹~")
}
}
LSP(Liskov Substitution Principle), Liskov Substitution Principle Objects in a program must be able to be converted to instances of subtypes without breaking the correctness of the program. In the example
TransactionalAccount
In the class, the method of the parent class Acout
deposit()
You can see that you can override and use it for instances of subtypes.
// 계좌 클래스
open class Account(val accountNumber: String, var balance: Double) {
open fun deposit(amount: Double) {
balance += amount
println("$amount 원이 입금되었습니다. 현재 잔액: $balance 원")
}
}
// 입출금 계좌 클래스
class TransactionalAccount(accountNumber: String, balance: Double) : Account(accountNumber, balance) {
override fun deposit(amount: Double) {
super.deposit(amount)
println("거래 내역이 저장되었습니다.")
}
}
// 메인 함수
fun main() {
val account: Account = TransactionalAccount("1234567890", 50000.0)
account.deposit(10000.0)
}
ISP(Interface Segregation Principle), Interface Segregation Principle Based on the principle that multiple interfaces for specific clients are better than one general-purpose interface, large chunks of interfaces are separated into specific, small units, allowing clients to use only the methods they absolutely need. The example below is an interface that violates the ISP principle. Since not all animals fly, it is ambiguous and in some cases is not a necessary method.
fly()
Contains .
// 헷갈리는 동물 인터페이스
interface ConfusingAnimal {
fun eat()
fun fly()
}
DIP(Dependency Inversion Principle), Dependency Inversion Principle The principle is that programmers should rely on abstraction and not on concreteness. If the client depends on the specific contents of the submodule, the disadvantage is that the client or upper module must be modified every time there is a change in the submodule. The example below is
BulbController
The class is
Bulb
It was created by inheriting an interface, and shows the dependency inversion phenomenon where methods use methods of the interface.
// 전구 인터페이스
interface Bulb {
fun turnOn()
fun turnOff()
}
// 전구 컨트롤러 클래스
class BulbController(private val bulb: Bulb) {
fun pressSwitch() {
bulb.turnOn()
bulb.turnOff()
}
}
### Domain-Driven Design (DDD)  Domain-driven design is a design method that considers the business domain as the center, originating from the idea that the value of software lies in the user's use. In other words, it begins with the need to prioritize software that can be used for the user's desired purpose over technology. Because it is determined from the user's perspective, the number of domains may vary depending on the perspective. However, by using DDD, developers can broaden their scope of thinking to include domain areas rather than simply being limited to technical areas. Bounded context is where the model is implemented and each separate software artifact is produced. The basic goal is to avoid confusion between collaborating team members and related departments by expressing it in a ubiquitous language. **Van Vernon's Domain Classification** + Main (core) domain + subdomain + Core subdomain + Business areas that can differentiate you from other competitors + High priority strategic investment areas + Where the greatest investment is needed + Support subdomain + Areas requiring custom development + Critical areas for the success of key subdomains + General subdomain + Areas that can be met immediately through purchasing existing products + Can be implemented directly by the team to which core/support subdomains are assigned --- [Domain-Driven Design Simplified.](https://medium.com/@jaysonmulwa/domain-driven-design-simplified-a03c732401c9) [Strategic Design in Domain Driven Design](https://engineering-skcc.github.io/msa/DDD-StrategicDesign/)
### Type System Strongly typed languages prevent program execution with a compilation error if the type check is not passed, but weakly typed languages do not prevent execution even if there is a type error at runtime. In most strongly typed languages
int
,
char
A type declaration like this is made, but a weak type is not used. But
Haskell
In the case of , it looks like a weak type because the compiler checks it through 'inference', but it belongs to the strong type family.
- Strong type
GO
,
ML
,
F#
- Strong type series
C#
,
Haskell
,
Java
- Drug type series
Javascript
,
Assembly
Static type languages, whose type is determined at compile time, belong to the strongly typed family. On the other hand, dynamically typed languages are mainly weakly typed, but because the types of variables are determined in the run type, they can be strongly typed languages. Opinions about types vary, but this is possible if a dynamically typed language performs strong type checking using type hints and type annotations. C, C++ is not strongly typed? If it doesn't pass the type check, it should always not run, but
union
This is because time errors cannot be detected in types. Therefore, it is desirable to view it as a strong-type ‘family’ language. Static type languages allow developers to work efficiently because they are fast to write code and have high flexibility, but they have the disadvantage of causing run-type errors and making debugging difficult. On the other hand, since compilation errors occur in statically typed languages, they can be said to have high stability by catching type errors in advance. However, the disadvantage is that the code is more complicated and less flexible.
Comments
No comments yet. Be the first!