diff --git a/googlemock/include/gmock/gmock-nice-strict.h b/googlemock/include/gmock/gmock-nice-strict.h
index 056d471417..acf39e083f 100644
--- a/googlemock/include/gmock/gmock-nice-strict.h
+++ b/googlemock/include/gmock/gmock-nice-strict.h
@@ -70,26 +70,11 @@
 #include "gmock/internal/gmock-port.h"
 
 namespace testing {
-template <class MockClass>
-class NiceMock;
-template <class MockClass>
-class NaggyMock;
-template <class MockClass>
-class StrictMock;
 
-namespace internal {
-template <typename T>
-std::true_type StrictnessModifierProbe(const NiceMock<T>&);
-template <typename T>
-std::true_type StrictnessModifierProbe(const NaggyMock<T>&);
-template <typename T>
-std::true_type StrictnessModifierProbe(const StrictMock<T>&);
-std::false_type StrictnessModifierProbe(...);
+template <class StrictNessModifier, class MockClass>
+class StrictNessBase;
 
-template <typename T>
-constexpr bool HasStrictnessModifier() {
-  return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;
-}
+namespace internal {
 
 // Base classes that register and deregister with testing::Mock to alter the
 // default behavior around uninteresting calls. Inheriting from one of these
@@ -143,61 +128,58 @@ class StrictMockImpl {
   }
 };
 
+template <typename T>
+std::true_type StrictnessModifierProbe(
+    const StrictNessBase<internal::NiceMockImpl<T>, T>&);
+template <typename T>
+std::true_type StrictnessModifierProbe(
+    const StrictNessBase<internal::NaggyMockImpl<T>, T>&);
+template <typename T>
+std::true_type StrictnessModifierProbe(
+    const StrictNessBase<internal::StrictMockImpl<T>, T>&);
+std::false_type StrictnessModifierProbe(...);
+
+template <typename T>
+constexpr bool HasStrictnessModifier() {
+  return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;
+}
+
 }  // namespace internal
 
-template <class MockClass>
-class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock
-    : private internal::NiceMockImpl<MockClass>,
-      public MockClass {
+template <class StrictNessModifier, class MockClass>
+class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictNessBase
+    : public StrictNessModifier {
  public:
-  static_assert(!internal::HasStrictnessModifier<MockClass>(),
+  static_assert(!internal::HasStrictnessModifier<StrictNessModifier>(),
                 "Can't apply NiceMock to a class hierarchy that already has a "
                 "strictness modifier. See "
                 "https://google.github.io/googletest/"
                 "gmock_cook_book.html#NiceStrictNaggy");
-  NiceMock() : MockClass() {
-    static_assert(sizeof(*this) == sizeof(MockClass),
-                  "The impl subclass shouldn't introduce any padding");
-  }
-
-  // Ideally, we would inherit base class's constructors through a using
-  // declaration, which would preserve their visibility. However, many existing
-  // tests rely on the fact that current implementation reexports protected
-  // constructors as public. These tests would need to be cleaned up first.
-
-  // Single argument constructor is special-cased so that it can be
-  // made explicit.
-  template <typename A>
-  explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
-    static_assert(sizeof(*this) == sizeof(MockClass),
-                  "The impl subclass shouldn't introduce any padding");
-  }
-
-  template <typename TArg1, typename TArg2, typename... An>
-  NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
-      : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
-                  std::forward<An>(args)...) {
-    static_assert(sizeof(*this) == sizeof(MockClass),
-                  "The impl subclass shouldn't introduce any padding");
-  }
+  StrictNessBase() = default;
 
  private:
-  NiceMock(const NiceMock&) = delete;
-  NiceMock& operator=(const NiceMock&) = delete;
+  StrictNessBase(const StrictNessBase&) = delete;
+  StrictNessBase& operator=(const StrictNessBase&) = delete;
 };
 
 template <class MockClass>
-class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
-    : private internal::NaggyMockImpl<MockClass>,
-      public MockClass {
-  static_assert(!internal::HasStrictnessModifier<MockClass>(),
-                "Can't apply NaggyMock to a class hierarchy that already has a "
-                "strictness modifier. See "
-                "https://google.github.io/googletest/"
-                "gmock_cook_book.html#NiceStrictNaggy");
+using NiceMockable =
+    StrictNessBase<internal::NiceMockImpl<MockClass>, MockClass>;
 
+template <class MockClass>
+using StrictMockable =
+    StrictNessBase<internal::StrictMockImpl<MockClass>, MockClass>;
+
+template <class MockClass>
+using NaggyMockable =
+    StrictNessBase<internal::NaggyMockImpl<MockClass>, MockClass>;
+
+template <class StrictNessModifier, class MockClass>
+class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictNessMockImplBase
+    : public StrictNessModifier,
+      public MockClass {
  public:
-  NaggyMock() : MockClass() {
+  StrictNessMockImplBase() : MockClass() {
     static_assert(sizeof(*this) == sizeof(MockClass),
                   "The impl subclass shouldn't introduce any padding");
   }
@@ -210,65 +192,31 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock
   // Single argument constructor is special-cased so that it can be
   // made explicit.
   template <typename A>
-  explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
+  explicit StrictNessMockImplBase(A&& arg) : MockClass(std::forward<A>(arg)) {
     static_assert(sizeof(*this) == sizeof(MockClass),
                   "The impl subclass shouldn't introduce any padding");
   }
 
   template <typename TArg1, typename TArg2, typename... An>
-  NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
+  StrictNessMockImplBase(TArg1&& arg1, TArg2&& arg2, An&&... args)
       : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
                   std::forward<An>(args)...) {
     static_assert(sizeof(*this) == sizeof(MockClass),
                   "The impl subclass shouldn't introduce any padding");
   }
-
- private:
-  NaggyMock(const NaggyMock&) = delete;
-  NaggyMock& operator=(const NaggyMock&) = delete;
 };
 
 template <class MockClass>
-class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock
-    : private internal::StrictMockImpl<MockClass>,
-      public MockClass {
- public:
-  static_assert(
-      !internal::HasStrictnessModifier<MockClass>(),
-      "Can't apply StrictMock to a class hierarchy that already has a "
-      "strictness modifier. See "
-      "https://google.github.io/googletest/"
-      "gmock_cook_book.html#NiceStrictNaggy");
-  StrictMock() : MockClass() {
-    static_assert(sizeof(*this) == sizeof(MockClass),
-                  "The impl subclass shouldn't introduce any padding");
-  }
-
-  // Ideally, we would inherit base class's constructors through a using
-  // declaration, which would preserve their visibility. However, many existing
-  // tests rely on the fact that current implementation reexports protected
-  // constructors as public. These tests would need to be cleaned up first.
-
-  // Single argument constructor is special-cased so that it can be
-  // made explicit.
-  template <typename A>
-  explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
-    static_assert(sizeof(*this) == sizeof(MockClass),
-                  "The impl subclass shouldn't introduce any padding");
-  }
+using NiceMock =
+    StrictNessMockImplBase<internal::NiceMockImpl<MockClass>, MockClass>;
 
-  template <typename TArg1, typename TArg2, typename... An>
-  StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)
-      : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),
-                  std::forward<An>(args)...) {
-    static_assert(sizeof(*this) == sizeof(MockClass),
-                  "The impl subclass shouldn't introduce any padding");
-  }
+template <class MockClass>
+using StrictMock =
+    StrictNessMockImplBase<internal::StrictMockImpl<MockClass>, MockClass>;
 
- private:
-  StrictMock(const StrictMock&) = delete;
-  StrictMock& operator=(const StrictMock&) = delete;
-};
+template <class MockClass>
+using NaggyMock =
+    StrictNessMockImplBase<internal::NaggyMockImpl<MockClass>, MockClass>;
 
 #undef GTEST_INTERNAL_EMPTY_BASE_CLASS
 
diff --git a/googlemock/test/gmock-nice-strict_test.cc b/googlemock/test/gmock-nice-strict_test.cc
index 95f0969035..19463ae69f 100644
--- a/googlemock/test/gmock-nice-strict_test.cc
+++ b/googlemock/test/gmock-nice-strict_test.cc
@@ -139,6 +139,21 @@ class MockBaz {
   MockBaz(MoveOnly) {}
 };
 
+class NiceMockModifier : public NiceMockable<NiceMockModifier> {
+ public:
+  NiceMockModifier() = default;
+};
+
+class NaggyMockModifier : public NaggyMockable<NaggyMockModifier> {
+ public:
+  NaggyMockModifier() = default;
+};
+
+class StrictMockModifier : public StrictMockable<StrictMockModifier> {
+ public:
+  StrictMockModifier() = default;
+};
+
 #if GTEST_HAS_STREAM_REDIRECTION
 
 // Tests that a raw mock generates warnings for uninteresting calls.
@@ -324,6 +339,13 @@ TEST(NiceMockTest, IsNaggy_IsNice_IsStrict) {
   EXPECT_FALSE(Mock::IsStrict(&nice_foo));
 }
 
+TEST(NiceMockTest, IsNaggy_IsNice_IsStrict_Class) {
+  NiceMockModifier nice_foo;
+  EXPECT_FALSE(Mock::IsNaggy(&nice_foo));
+  EXPECT_TRUE(Mock::IsNice(&nice_foo));
+  EXPECT_FALSE(Mock::IsStrict(&nice_foo));
+}
+
 #if GTEST_HAS_STREAM_REDIRECTION
 
 // Tests that a naggy mock generates warnings for uninteresting calls.
@@ -443,6 +465,13 @@ TEST(NaggyMockTest, IsNaggy_IsNice_IsStrict) {
   EXPECT_FALSE(Mock::IsStrict(&naggy_foo));
 }
 
+TEST(NaggyMockTest, IsNaggy_IsNice_IsStrict_Class) {
+  NaggyMockModifier naggy_foo;
+  EXPECT_TRUE(Mock::IsNaggy(&naggy_foo));
+  EXPECT_FALSE(Mock::IsNice(&naggy_foo));
+  EXPECT_FALSE(Mock::IsStrict(&naggy_foo));
+}
+
 // Tests that a strict mock allows expected calls.
 TEST(StrictMockTest, AllowsExpectedCall) {
   StrictMock<MockFoo> strict_foo;
@@ -537,5 +566,11 @@ TEST(StrictMockTest, IsNaggy_IsNice_IsStrict) {
   EXPECT_TRUE(Mock::IsStrict(&strict_foo));
 }
 
+TEST(StrictMockTest, IsNaggy_IsNice_IsStrict_Class) {
+  StrictMockModifier strict_foo;
+  EXPECT_FALSE(Mock::IsNaggy(&strict_foo));
+  EXPECT_FALSE(Mock::IsNice(&strict_foo));
+  EXPECT_TRUE(Mock::IsStrict(&strict_foo));
+}
 }  // namespace gmock_nice_strict_test
 }  // namespace testing