هیچ چیزی به اندازهی کدهای بد، ناخوانا، شلخته و سریع نوشته شده که با دقت طراحی نشده اند، روی کار یک تیم تأثیر نمیگذارد. پویایی تیم میتواند بهبود یابد، نیازمندیها دوباره تعریف شوند و زمان بندی میتواند اصلاح شود؛ اما، اگر کد بد کنترل کار را در دست بگیرد، سنگینی آن برای تیم بیشتر و بیشتر میشود. برنامه نویسان باید همیشه توسعه دهند. حتی اگر آنها فکر میکنند که مهارت و دانش کافی برای حرکت در پروژههای فعلی را دارند، نباید در آنجا متوقف شوند و شایسته است که آنها هر از گاهی مفاهیم، رویکردها، زبانها و چارچوبهای جدیدی را بیاموزند. یادگیری باید یک سفر باشد و نه یک مقصد.
برای تبدیل شدن به یک توسعه دهندهی بهتر نرم افزار، به دانش و مهارتهای عملی عمیقی در زمینهی توسعه و کیفیت نرم افزار نیاز دارید. این کتاب، برای تحلیل و بهبود کدهای نرم افزار شما، بحثهای مفصلی و بررسیهای اجمالی زیادی را ارائه میدهد. شما قادر خواهید بود تا از اصول، الگوها، تکنیکها و ابزارهای مورد نیاز برای نوشتن کد تمیز استفاده کنید.
کتاب Clean Code Fundamentals (مبانی کد تمیز)، مبانی کیفیت نرم افزار، اصول، الگوها و بهترین شیوههای نوشتن کد بهتر را بیان میکند. این کتاب همچنین شامل مثالهای بسیاری با کد جاوا و با پیچیدگی از کم به زیاد است. همچنین موارد دیگری مانند معیارهای نرم افزار، تست نرم افزار استاتیک و ابزارهایی که میتوانند به اندازه گیری کیفیت نرم افزار کمک کنند، پوشش داده خواهند شد.
هدف این کتاب چیست؟
خوانندگان کتاب Clean Code Fundamentals: Hands-on Guide to Understand the Fundamentals of Software Craftsmanship and Clean Code in Java، دانش و مهارتهای عمیقی را برای تجزیه و تحلیل، ارزیابی و بهبود کیفیت نرم افزار به دست میآورند. شما قادر خواهید بود تا از اصول، الگوها، تکنیکها و ابزارهای مورد نیاز برای نوشتن کد تمیز استفاده کنید.
درک مفاهیم مهم کیفیت نرم افزار در پروژههای جاوا:
- بهترین شیوه ها
- حوزه فنی و عملکردی
- مدلهای برنامه نویسی و توسعه
- ابزار ها
اهداف یادگیری:
- کسب دانش و مهارت برای تجزیه و تحلیل، ارزیابی و بهبود کیفیت نرم افزار
- یادگیری اصول، الگوها، تکنیکها و ابزارها
- عمیق کردن دانش فنی
کدام موضوعات را میتوانید انتظار داشته باشید؟
تست نرم افزار محدود به یک مرحله خاص از پروژه نیست. در حال حاضر، در مرحله کد نویسی یا فرآیند build، نقصهای نرم افزاری حیاتی که پیدا کردنشان سخت است را میتوان در کد منبع پیدا کرد و به همین منظور روشها و ابزارهای لازم در این کتاب ارائه شده اند.
در کنار سایر چیز ها، موضوعات زیر نیز پوشش داده شده اند:
- مروری بر مبانی کیفیت نرم افزار
- متریکهای نرم افزار، کاربرد متریک در عمل
- طراحی ساخت یافته، انسجام و اتصال
- مروری بر اصول، بهترین شیوهها و کدهای بودار
- انطباق و تأیید قراردادهای کد جاوا
- تست نرم افزار استاتیک، به ویژه تکنیکهای بررسی و تحلیل برنامه استاتیک
- اطمینان از کیفیت نرم افزار با ابزار هایی مانند SonarQube، PMD، SpotBugs، CheckStyle، ArchUnit و Dependency-Track
- تستهای نرم افزار با Junit و Mockito
- بررسی پوشش کد تست
- CI/CD
- اصول طراحی
- الگوهای طراحی (GoF)
چه کسی باید این کتاب را بخواند؟
من این کتاب را به این علت نوشتم که میخواهم به توسعه دهندگان کمک کنم تا در زمینه کد تمیز تجربه پیدا کنند یا آن را بهبود بخشند و به آنها احساس این که یک حرفه ای نرم افزار بودن چگونه است را بدهم. این در مورد حرفه ای بودن، عمل گرایی و افتخار است! این یک ذهنیت است، جایی که توسعه دهندگان نرم افزار تصمیم میگیرند که مسئولیت شغل خود را بر عهده بگیرند، ابزارها و تکنیکهای جدید را یاد بگیرند و مدام بهتر شوند. برای تبدیل شدن به یک Software Craftsmanship، سفری طولانی در پیش است. به همین دلیل است که میخواهم چندین تکنیک و شیوه را برای بهبود کیفیت کد و انگیزه بخشیدن به توسعه دهندگان به اشتراک بگذارم.
آنچه شما باید خودتان در مورد توسعه نرم افزار یاد بگیرید:
- توسعه دهندگان همیشه اشتباه میکنند - فقط میزان اشتباه توسعه دهندگان مختلف در بحثهای مربوط به معماری بی پایانشان متفاوت است!
- اگر چیزی بتواند بشکند، خواهد شکست - اطمینان حاصل کنید که یک پروژه بی عیب است!
- همه کدها بد هستند - فقط درجه بندیهای مختلفی از نقص در یک نرم افزار وجود دارد!
- همیشه باگی در جایی وجود دارد - شما فقط باید به اندازه کافی جستجو کنید!
- مهمترین چیز مشتری است - و آنها اهمیتی به فن آوریها و فرایندهای استفاده شده نمیدهند!
- توسعه پروژه روی کاغذ جواب نمیدهد - مشکلات فقط در طی مراحل توسعه مشخص میشوند!
- کمش هم زیاده - اگر چیزی لازم نیست، فقط آن را کنار بگذارید!
- فقط 20٪ کار ما شامل کدنویسی است - بقیه موارد عبارتند از طراحی، اشکال زدایی، آزمایش، جلسات، بحث و غیره.
- مشتری هرگز نمیداند چه میخواهد - هر کس فقط تصور مبهمی از نتیجه مطلوب دارد!
- کسی قبلاً این کار را انجام داده است - چرخ را دوباره اختراع نکنید!
Table of Contents:
- Preface
- What is the goal of this book?
- Which topics can you expect?
- Who should read this book?
- What you must learn about Software Development yourself?
- What about the code examples and typographic conventions?
- Which literature is this book based on?
- Giving feedback?
- 1 Introduction to Software Craftmanship and Clean Code
- 1.1 A Passion for Software Development
- 1.2 Manifesto for Software Craftsmanship
- 1.3 Clean Code Developer
- 1.4 Boy Scout Rule
- 1.5 Broken Windows Theory
- 1.6 Cargo Cult Programming
- 1.7 Knowledge - Expertise
- 2 Basics of Software Design
- 2.1 Software Design Pyramid
- 2.2 Basic concepts of OOD
- 2.3 Goals of Software Design
- 2.4 Symptoms of bad design
- 2.5 Criteria for good design
- 2.6 Information Hiding
- 2.7 Cohesion
- 2.8 Coupling
- 2.9 Cohesion - Coupling
- 2.10 Big Ball of Mud
- 2.11 Architecture Principles
- 2.12 Cognitive Psychology and Architectural Principles
- 2.13 Layered Architecture
- 2.13.1 Use of Layered Architecture
- 2.13.2 Violated Layered Architecture
- 2.13.3 Horizontal Layering
- 2.13.4 Feature Based Layering - Single package
- 2.13.5 Feature Based Layering - Slices before layers
- 2.13.6 Feature Based Layering – Hexagonal Architecture
- 2.13.7 The Java Module System
- 2.14 Architecture Documentation
- 2.15 Testing the Architecture and Design
- 2.16 Software Engineering Values
- 2.17 Team Charter
- 3 Java Best Practices
- 3.1 Communicate through code
- 3.1.1 Use Java code conventions and avoid misinformation
- 3.1.2 Choose an expressive name and avoid mental mapping
- 3.1.3 Make differences clear with meaningful variable names
- 3.1.4 Use pronounceable names
- 3.1.5 Do not hurt the readers
- 3.1.6 Don`t add redundant context
- 3.1.7 Don’t add words without additional meaning
- 3.1.8 Don’t use and or or in method names
- 3.1.9 Respect the order within classes
- 3.1.10 Group by line break
- 3.1.11 Prefer self-explanatory code instead of comments
- 3.1.12 Refactor step by step
- 3.2 Bad comments
- 3.2.1 Redundant comments
- 3.2.2 Misleading comments
- 3.2.3 Mandatory comments
- 3.2.4 Diary comments
- 3.2.5 Gossip
- 3.2.6 Position identifier
- 3.2.7 Write-ups and incidental remarks
- 3.2.8 Don’t leave commented out code in your codebase
- 3.2.9 Rules for commenting
- 3.3 Classes and objects
- 3.3.1 Classes
- 3.3.2 Functions
- 3.3.3 Variables
- 3.4 Shapes of code
- 3.4.1 Spikes
- 3.4.2 Paragraphs
- 3.4.3 Paragraphs with headers
- 3.4.4 Suspicious comments
- 3.4.5 Intensive use of an object
- 3.5 Avoid instantiation for utility classes
- 3.6 Use immutable objects
- 3.7 Prefer records for immutability
- 3.8 Provide immutable decorators for sensitive mutable classes
- 3.9 Avoid constant interfaces
- 3.10 Avoid global constant classes
- 3.11 Favour composition over inheritance
- 3.12 Use the @Override Annotation
- 3.13 Use the @FunctionalInterface Annotation
- 3.14 Prefer returning Null-Objects over null
- 3.15 Avoid null as method parameter
- 3.16 Prefer enhanced loops over for loops
- 3.17 Code against interfaces not implementations
- 3.18 Use existing exceptions
- 3.19 Validate method parameter
- 3.20 Prevent NullPointerException for String comparison
- 3.21 Safely cast long to int
- 3.22 Convert integers to floating point for floating-point math operations
- 3.23 Use Generics in favour of raw types
- 3.24 Prefer enums over int constants
- 3.25 Be aware of the contract between equals and hashCode
- 3.26 Use text blocks for multi-line strings
- 3.27 Use always braces for the body of all statements
- 3.28 Pre calculate the length in loops
- 3.29 Avoid slow instantiation of String
- 3.30 Use StringBuilder for concatenation
- 3.31 Reduce lookups in collection containers
- 3.32 Instantiate wrapper objects with valueOf
- 3.33 Use entrySet for iterating
- 3.34 Use isEmpty() for String length
- 3.35 Reduce the number of casts
- 4 Software Quality Assurance
- 4.1 Test Pyramid
- 4.2 Test Classification
- 4.3 Test-driven Development (TDD)
- 4.4 Unit testing with JUnit 5
- 4.4.1 Unit Tests
- 4.4.2 JUnit 5
- 4.4.3 First unit test
- 4.4.4 Assertions
- 4.4.4.1 assertEquals() / assertArrayEquals()
- 4.4.4.2 assertSame() / assertNotSame()
- 4.4.4.3 assertTrue() / assertFalse() / assertAll()
- 4.4.4.4 assertNull() / assertNotNull()
- 4.4.4.5 assertThrows()
- 4.4.4.6 assertTimeout()
- 4.4.4.7 fail()
- 4.4.5 Annotations
- 4.4.5.1 @Test
- 4.4.5.2 @BeforeEach / @AfterEach
- 4.4.5.3 @BeforeAll / @AfterAll
- 4.4.5.4 @Disabled
- 4.4.5.5 @DisplayName
- 4.4.5.6 @Tag
- 4.4.5.7 @Timeout
- 4.4.6 Assumptions
- 4.4.6.1 assumeFalse()
- 4.4.6.2 assumeTrue()
- 4.4.6.3 assumingThat()
- 4.4.7 Parameterized Tests
- 4.4.7.1 @ValueSource
- 4.4.7.2 @MethodSource
- 4.4.7.3 @CsvSource
- 4.4.7.4 @CsvFileSource
- 4.4.7.5 @ArgumentsSource
- 4.5 More on Unit Tests
- 4.5.1 Heuristics
- 4.5.2 Naming of test methods
- 4.5.3 Object Mother
- 4.5.4 Test Data Builder
- 4.5.5 F.I.R.S.T
- 4.6 Mocking with Mockito
- 4.6.1 Types of Test Double
- 4.6.2 Activation
- 4.6.3 Annotations
- 4.6.3.1 @Mock
- 4.6.3.2 @Spy
- 4.6.3.3 @Captor
- 4.7 Code Coverage
- 4.8 Static Code Analysis
- 4.9 Continuous Integration
- 4.9.1 Differences between CI, CD and CD
- 4.9.2 CI Workflow
- 4.9.3 Preconditions
- 4.9.4 Advantages and Disadvantages
- 4.9.5 Best Practices
- 5 Design Principles
- 5.1 Goal of Design Principles
- 5.2 Overview of Design Principles
- 5.3 SOLID Principles
- 5.3.1 Single Responsibility Principle
- 5.3.1.1 Example: Modem
- 5.3.1.2 Example: Book
- 5.3.2 Open Closed Principle
- 5.3.2.1 Example: LoanRequestHandler
- 5.3.2.2 Example: Shape
- 5.3.2.3 Example: HumanResourceDepartment
- 5.3.2.4 Example: Calculator
- 5.3.2.5 Example: FileParser
- 5.3.3 Liskov Substitution Principle
- 5.3.3.1 Example: Rectangle
- 5.3.3.2 Example: Coupon
- 5.3.4 Interface Segregation Principle
- 5.3.4.1 Example: MultiFunctionDevice
- 5.3.4.2 Example: TechEmployee
- 5.3.5 Dependency Inversion Principle
- 5.3.5.1 Example: UserService
- 5.3.5.2 Example: Logger
- 5.4 Packaging Principles - Cohesion
- 5.4.1 Release Reuse Equivalency Principle
- 5.4.2 Common Closure Principle
- 5.4.3 Common Reuse Principle
- 5.5 Packaging Principles - Coupling
- 5.5.1 Acyclic Dependencies Principle
- 5.5.1.1 Example: Cyclic dependency
- 5.5.2 Stable Dependencies Principle
- 5.5.3 Stable Abstractions Principles
- 5.6 Further Design Principles
- 5.6.1 Speaking Code Principle
- 5.6.2 Keep It Simple (and) Stupid!
- 5.6.3 Don’t Repeat Yourself / Once and Only Once
- 5.6.4 You Ain’t Gonna Need It!
- 5.6.5 Separation Of Concerns
- 6 Design Patterns of the Gang of Four
- 6.1 Creational
- 6.1.1 Singleton
- 6.1.1.1 Example: Lazy loading
- 6.1.1.2 Example: Eager loading
- 6.1.1.3 Example: Enum singleton
- 6.1.2 Builder
- 6.1.2.1 Example: MealBuilder
- 6.1.2.2 Example: PizzaBuilder
- 6.1.2.3 Example: Email
- 6.1.2.4 Example: ImmutablePerson
- 6.1.3 Factory Method
- 6.1.3.1 Example: Logger
- 6.1.3.2 Example: Department
- 6.1.4 Abstract Factory
- 6.1.4.1 Example: Car
- 6.1.5 Prototype
- 6.1.5.1 Example: Person - Shallow copy
- 6.1.5.2 Example: Person - Deep copy
- 6.1.5.3 Example: Person - Copy constructor / factory
- 6.2 Structural
- 6.2.1 Facade
- 6.2.1.1 Example: Travel
- 6.2.2 Decorator
- 6.2.2.1 Example: Message
- 6.2.2.2 Example: Window
- 6.2.3 Adapter
- 6.2.3.1 Example: Sorter
- 6.2.3.2 Example: TextFormatter
- 6.2.4 Composite
- 6.2.4.1 Example: Graphic
- 6.2.4.2 Example: Organization Chart
- 6.2.5 Bridge
- 6.2.5.1 Example: Message
- 6.2.5.2 Example: Television
- 6.2.6 Flyweight
- 6.2.6.1 Example: Font
- 6.2.6.2 Example: City
- 6.2.7 Proxy
- 6.2.7.1 Example: Spaceship
- 6.2.7.2 Example: ImageViewer
- 6.3 Behavioural
- 6.3.1 State
- 6.3.1.1 Example: MP3Player
- 6.3.1.2 Example: Door
- 6.3.2 Template Method
- 6.3.2.1 Example: Compiler
- 6.3.2.2 Example: Callbackable
- 6.3.3 Strategy
- 6.3.3.1 Example: Compression
- 6.3.3.2 Example: LogFormatter
- 6.3.4 Observer
- 6.3.4.1 Example: DataStore
- 6.3.4.2 Example: Influencer
- 6.3.5 Chain of Responsibility
- 6.3.5.1 Example: Purchase
- 6.3.5.2 Example: Authentication
- 6.3.6 Command
- 6.3.6.1 Example: FileSystem
- 6.3.6.2 Example: Television
- 6.3.7 Interpreter
- 6.3.8 Iterator
- 6.3.9 Mediator
- 6.3.10 Memento
- 6.3.11 Visitor
- 6.3.11.1 Example: Fridge
- 6.3.11.2 Example: Figures
- Notes